Load packages

library(tidyverse) # tidy style coding
library(brms) # Bayesian models
library(bayesplot) # pretty bayes visuals
library(tidybayes) # Bayesian aesthetics
library(loo) # to use information criteria in brms models
library(MetBrewer) # colours
library(rcartocolor) # more colours
library(kableExtra) # tables
library(patchwork) # putting plots together
library(DT) # for search- and saveable tables
library(ggdist) # for ribbon plot

Mortality analysis

\(~\)

We conducted single-pair full-sibling crosses to erode heterozygosity across the genome, thereby exposing mutation load. Our proxies for mutation load - extinction rate and productivity decline - may also have been affected by differences in the intensity of interlocus sexual conflict between lineages carrying autosomes with different selection response histories. **We specifically designed our experiment to minimise this effect*, by enforcing monogamy between all breeding individuals across the extinction assay. However, we cannot discount males carrying male-limited autosomes and/ or control autosomes being more harmful to females than males carrying autosomes with a female-limited selection response history. This might occur because male harm is a by-product of male-male competition, which cannot respond to selection in the female-limited treatments. Furthermore, traits genetically correlated with harm such as activity levels or metabolic rate may be selected in the opposite direction among females, as these traits are highly sexually dimorphic. This may drive the evolution of reduced harm during female-limited evolution.

We observe 135 female (6.2%) and 21 (1%) male mortalities across the 2184 Drosophila vials used during the 20 generations of the experiment (we do not include the 9 final generations observed in Block 1 in this analysis). Male mortality did not occur often enough to provide the power required for formal analysis. We instead focus on modelling female mortality and test whether this is affected by selection response history.

We test this hypothesis to assess whether it is required to censor lineages where the breeding female died in the generation of extinction.

\(~\)

Load in the data

mortality_data <- 
  read_csv("Data/Mortality_data.csv") %>% 
  rowid_to_column("Lineage") %>% 
  pivot_longer(cols = 8:27, names_to = "Generation", values_to = "Female_mortality") %>% 
  mutate(across(1:7, as.factor),
         Generation = as.integer(str_remove(Generation, "Gen_")),
         Male_mortality = Female_mortality,
         Female_mortality = if_else(Female_mortality == "FEMALE" | Female_mortality == "BOTH", 1, 0),
         Male_mortality = if_else(Male_mortality == "MALE" | Male_mortality == "BOTH", 1, 0))

\(~\)

Modelling approach

\(~\)

We fit a binomial model with Evolution_treatment and Block as fixed effects as well as Lineage and Cross as random effects.

mortality_model <- 
  brm(Female_mortality ~ 1 + Treatment + Block + (1|Cross) + (1|Lineage),
      data = mortality_data %>% filter(Female_mortality != "NA"),
      family = bernoulli,
      prior = c(prior(normal(0, 2), class = Intercept),
                prior(normal(0, 1), class = b),
                prior(exponential(1), class = sd)),
      iter = 4000, warmup = 2000, chains = 4, cores = 4, seed = 1,
      control = list(adapt_delta = 0.95),
      file = "Fits/mortality_model")

Extract model predictions and plot

# these are specific to block 1, but this doesn't really matter because there is no interaction between treatment and block.

mortality_predictions <-
  mortality_model %>% 
  as_draws_df() %>% 
  mutate(Control = inv_logit_scaled(b_Intercept),
         `Female-limited` = inv_logit_scaled(b_Intercept + b_TreatmentFemale),
         `Male-limited` = inv_logit_scaled(b_Intercept + b_TreatmentMale)) %>% 
  select(Control, `Female-limited`, `Male-limited`)

# put in easy to plot format

mortality_predictions_long <-
  mortality_predictions %>% 
  pivot_longer(cols = everything(), names_to = "Evolution_treatment", values_to = "Mortality")

# calculate the differences between each treatment

mortality_diff <-
  mortality_predictions %>% 
  mutate(`Control - Male-limited` = Control - `Male-limited`,
         `Male-limited - Female-limited` = `Male-limited` - `Female-limited`,
         `Control - Female-limited` = Control - `Female-limited`) %>% 
  pivot_longer(cols = 4:6, names_to = "Difference_contrast", values_to = "Difference") %>% 
  select(contains("Diff"))

Build Figure SX

mortality_plot <-
  mortality_predictions_long %>% 
  ggplot(aes(x = Mortality, y = Evolution_treatment)) +
    stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white", 
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x= "Female mortality (prop.)", y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

mortality_diff_plot <- 
  mortality_diff %>% 
  ggplot(aes(x = Difference, y = fct_relevel(Difference_contrast, "Female - Control", "Male - Female", "Male - Control"))) +
  stat_halfeye(aes(fill = Difference_contrast), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) + 
  scale_fill_manual(values = c(carto_pal(7, "Peach")[2], carto_pal(7, "Purp")[1], carto_pal(7, "TealGrn")[1])) +
  geom_vline(xintercept = 0, linetype = 2, colour = "black", size = 1) +
  labs(x = "Diff. in mortality", y = "Treatment contrast") +
  #scale_x_continuous(breaks=seq(-4, 6, 2)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(),
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

mortality_plot / mortality_diff_plot

Figure SX.

\(~\)

Female mortality is less frequent in lineages with female-limited selection response histories, suggesting that male harm may be less intense in these lineages. To avoid this confounding our measure of mutation load, we can censor extinction events that co-occur with female mortality.

\(~\)

Extinction analysis

Load in the extinction data

\(~\)

extinction_data <- 
  read_csv("Data/Extinction_data.csv") 

# Block 1 runs for 29 generations, while Block 2 only runs for 20. To calculate the censoring variable, we need to split these by Block, mutate the data, then rebind them 

Block_1 <-
  extinction_data %>% 
  filter(Block == "1") %>% 
  # here we create a censoring column. If the family a) escaped or was killed by something unrelated to the experiment or b) survived the 20 generations of the experiment, then we code a value of 1. If the family went extinct, we code a value of 0. This allows us to right censor the data, thereby preserving the information it provides on extinction.
  mutate(across(Gen_1:Gen_29, ~replace_na(.x, "Escape")),
         Censored_alive = if_else(Gen_29 == "YES", 1, 0),
         Censored_escape = if_else(Gen_29 == "Escape", 1, 0),
         Censored = Censored_alive + Censored_escape,
         across(Gen_1:Gen_29, ~if_else(.x == "YES", 1, 0)))
        

Block_2 <-
  extinction_data %>% 
  filter(Block == "2") %>% 
  # here we create a censoring column. If the family a) escaped or was killed by something unrelated to the experiment or b) survived the 20 generations of the experiment, then we code a value of 1. If the family went extinct, we code a value of 0. This allows us to right censor the data, thereby preserving the information it provides on extinction.
  mutate(across(Gen_1:Gen_20, ~replace_na(.x, "Escape")),
         across(Gen_21:Gen_29, ~replace_na(.x, "Not measured")),
         Censored_alive = if_else(Gen_20 == "YES", 1, 0),
         Censored_escape = if_else(Gen_20 == "Escape", 1, 0),
         Censored = Censored_alive + Censored_escape,
         across(Gen_1:Gen_29, ~if_else(.x == "YES", 1, 0)))

# combine the Blocked data back into a single tibble

extinction_data_wrangled <-
  rbind(Block_1, Block_2) %>%
  mutate(across(1:7, as.factor), 
         Gens_to_extinct = Gen_1 + Gen_2 + Gen_3 + Gen_4 + 
           Gen_5 + Gen_6 + Gen_7 + Gen_8 + Gen_9 + Gen_10 + 
           Gen_11 + Gen_12 + Gen_13 + Gen_14 + Gen_15 + Gen_16 + 
           Gen_17 + Gen_18 + Gen_19 + Gen_20 + Gen_21 + Gen_22 + 
           Gen_23 + Gen_24 + Gen_25 + Gen_26 + Gen_27 + Gen_28 + Gen_29 + 1) %>% 
  rename(Evolution_treatment = Treatment, Lineage  = ID) %>% 
  select(Mother_strain, Father_strain, Cross, Lineage, Block, 
         Evolution_treatment, Gens_to_extinct, Gen_1:Gen_29, Censored_alive, 
         Censored_escape, Censored)

# Find the extinctions that co-occur with female mortality

extinction_mortality <-
  left_join(
    extinction_data_wrangled %>% 
      pivot_longer(cols = 8:36, names_to = "Generation", values_to = "Extant") %>% 
      mutate(Generation = as.integer(str_remove(Generation, "Gen_"))),
    
    mortality_data
  ) %>% 
  filter(Extant == 0 & Female_mortality == 1) %>% 
  mutate(Censored_mortality = 1) %>% 
  select(Lineage, Censored_mortality)

extinction_data_wrangled <- left_join(extinction_data_wrangled, extinction_mortality) %>% 
  mutate(Censored_mortality = if_else(is.na(Censored_mortality), 0, 1),
         Censored = Censored + Censored_mortality)

# Create a function to build HTML searchable tables

my_data_table <- function(df){
  datatable(
    df, rownames=FALSE,
    autoHideNavigation = TRUE,
    extensions = c("Scroller",  "Buttons"),
    options = list(
      dom = 'Bfrtip',
      deferRender=TRUE,
      scrollX=TRUE, scrollY=400,
      scrollCollapse=TRUE,
      buttons =
        list('pageLength', 'colvis', 'csv', list(
          extend = 'pdf',
          pageSize = 'A4',
          orientation = 'landscape',
          filename = 'extinction_data')),
      pageLength = 500
    )
  )
}

my_data_table(extinction_data_wrangled)

Column explanations

Mother strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same Evolution_treatment. This column shows the strain that the founding female of the lineage was derived from.

Father strain: we measured extinction and productivity of families derived from 36 different crosses. Crosses were only conducted between strains that experienced the same evolution treatment. This column shows the strain that the founding male of the lineage was derived from.

Cross: an identifying ID for each of the 36 combinations of Mother strain and Father strain.

Lineage: lines of flies founded by single inseminated females in generation zero. We generated the next generation of each lineage by crossing a single full-sibling dyad.

Block: the experiment was run in 2 distinct blocks, using flies separated by 9 generations.

Evolution_treatment: the strains had been exposed to one of three evolutionary conditions for 20 generations: a female-limited response to selection, a male-limited response and a control condition where an evolutionary response occurred in both sexes.

Gens_to_extinction: the number of generations the lineage survived until it went extinct.

Gen_1:29: a 1 indicates the lineage was extant for the generation in question, while a 0 indicates extinction. Note that we continued propagating surviving lineages from Block 1 until generation 29, which coincided with generation 20 for lineages belonging to the second Block.

Censored: if the lineage 1) ended because flies escaped or were killed by something unrelated to the experiment, 2) went extinct because of breeding female mortality or 3) was extant in teh final generation of the experiment, then we coded a value of 1. If the lineage went extinct, we coded a value of 0. This allows us to right censor the data as per the brms syntax, thereby preserving the information these censored cases provide on extinction.

\(~\)

Modelling approach

\(~\)

We fit a weibull survival model to estimate , the extinction rate of the lineages used in our experiment. The weibull model is an extension of an exponential decay model, and includes an additional shape parameter, which allows to vary across generations of inbreeding.

Response variable

Gens_to_extinct is our response - a continuous variable that runs from 1 to 30 generations. Note that we measured extinction up until generation 29 in Block 1 and generation 20 in Block 2. A value of 30 indicates that the lineage was extant at the end of the experiment in Block 1, while a value of 21 indicates this in Block 2. We also include right censoring, to account for lineages extant at the end of the experiment, or that were removed from the experiment by a handling error. Censoring enables the inclusion of this ‘incomplete’ data in the model.

Fixed effects

Evolution_treatment: we include this to test for a causal effect of sex-limited experimental evolution on mutation load.

Block: extinction rate might differ between the blocks we split our experiment up into e.g. because of microvariation in the lab brought about because of a change of season, slight inconsistencies in Drosophila food consistency etc.

Varying/Random effects

Cross: we initiated each lineage by crossing two strains belonging to the same evolution treatment. There were 12 levels of cross nested within evolution treatment, for a total of 36 crosses. We kept lineages from the same Cross and Block in the same column of the Drosophila vial trays, so incuding this variable also controls for micro-environmental variation caused by within-tray position. We used this random effect in our first model.

Mother_strain and Father_strain: Used as an alternative to Cross in our second model. In this case, we fit a multi-membership model, where each lineage simultaneously belongs to two levels of the Cross random effect. That is, each lineage was founded my a mother from \(strain_i\) and a father from \(strain_j\) and they therefore always belong to two levels of strain.

Multi-membership vs single-membership

While the multi-membership approach may initially seem the more powerful of the two random effect structures, we favour the single-membership approach for several reasons. First, our primary aim is to estimate the overall causal effect of evolution treatment on generations to extinction, rather than that of each strain (nested within evolution treatment). Given that we balanced our crossing design so that each strain is equally represented in the experiment, estimation for each strain is not integral. Second, Cross captures nuisance environmental variation that Strain does not. We distributed lineages throughout three Drosophila vial trays by placing lineages from the same cross in the same column. Across the columns we split lineages up by evolution treatment, such that column one contained lineages from the female-limited treatment, column two contained lineages from the male-limited treatment and column three contained lineages from the control treatment. We repeated this pattern until all 36 crosses filled a column. As a strain is used in multiple crosses, it is widely distirbuted throughout the trays and therefore does not capture a location effect like cross does. We are of the opinion that controlling for this environmental variation is of greater importance than strain level differences in mutation load, which both cross and evolution treatment also contain information for.

Finally, we fit both models and use leave one out (LOO) cross validation to formally assess which model has better expected predictive accuracy, both in and out of sample.

Priors

We fit moderately informative priors, with the aim to regularise our posterior estimates and improve model fitting by ruling out non-sensical values.

Fit the models

extinction_model_sm <-
  brm(data = extinction_data_wrangled,
      family = weibull,
      bf(Gens_to_extinct | cens(Censored) ~ 1 + Evolution_treatment + Block + (1|Cross),
         shape ~ 1 + Evolution_treatment + Block),
      prior = c(prior(normal(0, 1), class = Intercept), 
                prior(normal(0, 1), class = b),
                prior(exponential(1), class = sd),
                prior(normal(0, 1), class = b, dpar = shape)), 
      iter = 8000, warmup = 4000, chains = 4, cores = 4,
      seed = 1, control = list(adapt_delta = .9, max_treedepth = 10),
       file = "Fits/extinction_model_mortality")

extinction_model_sm <- add_criterion(extinction_model_sm, criterion = "loo")

# the model does not converge when we try and fit a treatment * block interaction

extinction_model_mm <-
  brm(data = extinction_data_wrangled,
      family = weibull,
      bf(Gens_to_extinct | cens(Censored) ~ 1 + Evolution_treatment + Block + (1|mm(Mother_strain, Father_strain)),
      shape ~ 1 + Evolution_treatment + Block),
      prior = c(prior(normal(0, 1), class = Intercept), 
                prior(normal(0, 1), class = b),
                prior(exponential(1), class = sd),
                prior(normal(0, 1), class = b, dpar = shape)), 
      iter = 8000, warmup = 4000, chains = 4, cores = 4,
      seed = 1, control = list(adapt_delta = 0.9, max_treedepth = 15),
      file = "Fits/extinction_model_mm")

extinction_model_mm <- add_criterion(extinction_model_mm, criterion = "loo")

\(~\)

Model diagnostics

\(~\)

Compare models using LOO, a bayesian information criteria

loo_compare(extinction_model_sm, extinction_model_mm)  %>% 
  kable(digits = 3) %>% 
  kable_styling()
elpd_diff se_diff elpd_loo se_elpd_loo p_loo se_p_loo looic se_looic
extinction_model_sm 0.000 0.000 -1042.921 20.194 23.761 2.946 2085.842 40.389
extinction_model_mm -0.937 2.625 -1043.858 20.274 15.366 2.347 2087.716 40.548

The single-membership model performs slightly better. We present results from this model.

Lets see how the model recapitulates the data

pp_check(extinction_model_sm, type = "hist", ndraws = 11, binwidth = 1) +
  theme_minimal() +
  theme(panel.background = element_blank())

\(~\)

Interpreting model output

\(~\)

We can initially ignore the shape parameter and find the mean rate of extinction, averaged across all generations, using the equation

\(\lambda= \frac{1}{e^\mu}\)

First find distributions of \(\mu\) for each of the three treatments.

inverse_rate_weibull <-
  extinction_model_sm %>% 
  as_draws_df() %>% 
  transmute(`Control B1` = b_Intercept, 
         `Female_limited B1` = b_Intercept + b_Evolution_treatmentFemale,
         `Male_limited B1` = b_Intercept + b_Evolution_treatmentMale,
         `Control B2` = b_Intercept + b_Block2, 
         `Female_limited B2` = b_Intercept + b_Evolution_treatmentFemale + b_Block2,
         `Male_limited B2` = b_Intercept + b_Evolution_treatmentMale + b_Block2)

Now lets plug these distributions into the equation to find mean estimates of \(\lambda\).

  inverse_rate_weibull %>% 
  mutate(across(1:6, ~1 / exp(.x))) %>% 
  mutate(across(everything(), ~mean(.x))) %>% 
  distinct()
## # A tibble: 1 × 6
##   `Control B1` `Female_limited B1` `Male_limited B1` Control B…¹ Femal…² Male_…³
##          <dbl>               <dbl>             <dbl>       <dbl>   <dbl>   <dbl>
## 1        0.142               0.130             0.111       0.121   0.111  0.0944
## # … with abbreviated variable names ¹​`Control B2`, ²​`Female_limited B2`,
## #   ³​`Male_limited B2`

This is the rate of extinction per generation, averaged across all generations. However, the weibull family allows a dynamic rate rather the the constant rate that the exponential constrains it to.

Following this post, the weibull survival function can be found using the following transformation:

\(\lambda= \frac{e^\mu}{\gamma(1 + \frac{1}{k})}\)

where \(k\) is the shape parameter estimated in brms

Then we can find survival at generation \(t\) using

\(S = e^{-(\frac{t}{\lambda})^k}\)

We plug in a vector with 16000 draws from the posterior distribution for 1) of each inheritance treatment and 2) \(k\) the shape parameter to find distributions of the proportion of surviving lineages at each generation.

# Find lambda for the three treatments. 

lambda_weibull <-
  extinction_model_sm %>% 
  as_draws_df() %>% 
  transmute(`Control B1` = b_Intercept, 
            `Female_limited B1` = b_Intercept + b_Evolution_treatmentFemale,
            `Male_limited B1` = b_Intercept + b_Evolution_treatmentMale,
            `Control B2` = b_Intercept + b_Block2, 
            `Female_limited B2` = b_Intercept + b_Evolution_treatmentFemale + b_Block2,
            `Male_limited B2` = b_Intercept + b_Evolution_treatmentMale + b_Block2,
            shape_control_B1 = exp(b_shape_Intercept),
            shape_female_B1 = exp(b_shape_Intercept + b_shape_Evolution_treatmentFemale),
            shape_male_B1 = exp(b_shape_Intercept + b_shape_Evolution_treatmentMale),
            shape_control_B2 = exp(b_shape_Intercept + b_shape_Block2),
            shape_female_B2 = exp(b_shape_Intercept + b_shape_Evolution_treatmentFemale + b_shape_Block2),
            shape_male_B2 = exp(b_shape_Intercept + b_shape_Evolution_treatmentMale + b_shape_Block2)) %>% 
  mutate(Control_lambda_B1 = exp(`Control B1`) / gamma(1 + 1/shape_control_B1),
         Female_lambda_B1 = exp(`Female_limited B1`) / gamma(1 + 1/shape_female_B1),
         Male_lambda_B1 = exp(`Male_limited B1`) / gamma(1 + 1/shape_male_B1),
         Control_lambda_B2 = exp(`Control B2`) / gamma(1 + 1/shape_control_B2),
         Female_lambda_B2 = exp(`Female_limited B2`) / gamma(1 + 1/shape_female_B2),
         Male_lambda_B2 = exp(`Male_limited B2`) / gamma(1 + 1/shape_male_B2)) %>% 
  select(contains(c("lambda", "shape")))

# Now find survival proportion at generations 1-29

Weibull_survival_curve <- 
  lambda_weibull %>% 
  mutate(#Block 1
    Control_0_B1  = exp(-(0/Control_lambda_B1)^shape_control_B1),  
    Control_1_B1  = exp(-(1/Control_lambda_B1)^shape_control_B1),
    Control_2_B1  = exp(-(2/Control_lambda_B1)^shape_control_B1),
    Control_3_B1  = exp(-(3/Control_lambda_B1)^shape_control_B1),
    Control_4_B1  = exp(-(4/Control_lambda_B1)^shape_control_B1),
    Control_5_B1  = exp(-(5/Control_lambda_B1)^shape_control_B1),
    Control_6_B1  = exp(-(6/Control_lambda_B1)^shape_control_B1),
    Control_7_B1  = exp(-(7/Control_lambda_B1)^shape_control_B1),
    Control_8_B1 = exp(-(8/Control_lambda_B1)^shape_control_B1),
    Control_9_B1 = exp(-(9/Control_lambda_B1)^shape_control_B1),
    Control_10_B1 = exp(-(10/Control_lambda_B1)^shape_control_B1),
    Control_11_B1 = exp(-(11/Control_lambda_B1)^shape_control_B1),
    Control_12_B1 = exp(-(12/Control_lambda_B1)^shape_control_B1),
    Control_13_B1 = exp(-(13/Control_lambda_B1)^shape_control_B1),
    Control_14_B1 = exp(-(14/Control_lambda_B1)^shape_control_B1),
    Control_15_B1 = exp(-(15/Control_lambda_B1)^shape_control_B1),
    Control_16_B1 = exp(-(16/Control_lambda_B1)^shape_control_B1),
    Control_17_B1 = exp(-(17/Control_lambda_B1)^shape_control_B1),
    Control_18_B1 = exp(-(18/Control_lambda_B1)^shape_control_B1),
    Control_19_B1 = exp(-(19/Control_lambda_B1)^shape_control_B1),
    Control_20_B1 = exp(-(20/Control_lambda_B1)^shape_control_B1),
    Control_21_B1 = exp(-(21/Control_lambda_B1)^shape_control_B1),
    Control_22_B1 = exp(-(22/Control_lambda_B1)^shape_control_B1),
    Control_23_B1 = exp(-(23/Control_lambda_B1)^shape_control_B1),
    Control_24_B1 = exp(-(24/Control_lambda_B1)^shape_control_B1),
    Control_25_B1 = exp(-(25/Control_lambda_B1)^shape_control_B1),
    Control_26_B1 = exp(-(26/Control_lambda_B1)^shape_control_B1),
    Control_27_B1 = exp(-(27/Control_lambda_B1)^shape_control_B1),
    Control_28_B1 = exp(-(28/Control_lambda_B1)^shape_control_B1),
    Control_29_B1 = exp(-(29/Control_lambda_B1)^shape_control_B1),
    Female_0_B1  = exp(-(0/Female_lambda_B1)^shape_female_B1),
    Female_1_B1  = exp(-(1/Female_lambda_B1)^shape_female_B1),
    Female_2_B1  = exp(-(2/Female_lambda_B1)^shape_female_B1),
    Female_3_B1  = exp(-(3/Female_lambda_B1)^shape_female_B1),
    Female_4_B1  = exp(-(4/Female_lambda_B1)^shape_female_B1),
    Female_5_B1  = exp(-(5/Female_lambda_B1)^shape_female_B1),
    Female_6_B1  = exp(-(6/Female_lambda_B1)^shape_female_B1),
    Female_7_B1  = exp(-(7/Female_lambda_B1)^shape_female_B1),
    Female_8_B1  = exp(-(8/Female_lambda_B1)^shape_female_B1),
    Female_9_B1  = exp(-(9/Female_lambda_B1)^shape_female_B1),
    Female_10_B1  = exp(-(10/Female_lambda_B1)^shape_female_B1),
    Female_11_B1  = exp(-(11/Female_lambda_B1)^shape_female_B1),
    Female_12_B1  = exp(-(12/Female_lambda_B1)^shape_female_B1),
    Female_13_B1  = exp(-(13/Female_lambda_B1)^shape_female_B1),
    Female_14_B1  = exp(-(14/Female_lambda_B1)^shape_female_B1),
    Female_15_B1  = exp(-(15/Female_lambda_B1)^shape_female_B1),
    Female_16_B1  = exp(-(16/Female_lambda_B1)^shape_female_B1),
    Female_17_B1  = exp(-(17/Female_lambda_B1)^shape_female_B1),
    Female_18_B1  = exp(-(18/Female_lambda_B1)^shape_female_B1),
    Female_19_B1  = exp(-(19/Female_lambda_B1)^shape_female_B1),
    Female_20_B1  = exp(-(20/Female_lambda_B1)^shape_female_B1),
    Female_21_B1 = exp(-(21/Female_lambda_B1)^shape_female_B1),
    Female_22_B1 = exp(-(22/Female_lambda_B1)^shape_female_B1),
    Female_23_B1 = exp(-(23/Female_lambda_B1)^shape_female_B1),
    Female_24_B1 = exp(-(24/Female_lambda_B1)^shape_female_B1),
    Female_25_B1 = exp(-(25/Female_lambda_B1)^shape_female_B1),
    Female_26_B1 = exp(-(26/Female_lambda_B1)^shape_female_B1),
    Female_27_B1 = exp(-(27/Female_lambda_B1)^shape_female_B1),
    Female_28_B1 = exp(-(28/Female_lambda_B1)^shape_female_B1),
    Female_29_B1 = exp(-(29/Female_lambda_B1)^shape_female_B1),
    Male_0_B1     = exp(-(0/Male_lambda_B1)^shape_male_B1),
    Male_1_B1     = exp(-(1/Male_lambda_B1)^shape_male_B1),
    Male_2_B1     = exp(-(2/Male_lambda_B1)^shape_male_B1),
    Male_3_B1     = exp(-(3/Male_lambda_B1)^shape_male_B1),
    Male_4_B1     = exp(-(4/Male_lambda_B1)^shape_male_B1),
    Male_5_B1     = exp(-(5/Male_lambda_B1)^shape_male_B1),
    Male_6_B1     = exp(-(6/Male_lambda_B1)^shape_male_B1),
    Male_7_B1     = exp(-(7/Male_lambda_B1)^shape_male_B1),
    Male_8_B1     = exp(-(8/Male_lambda_B1)^shape_male_B1),
    Male_9_B1     = exp(-(9/Male_lambda_B1)^shape_male_B1),
    Male_10_B1    = exp(-(10/Male_lambda_B1)^shape_male_B1),
    Male_11_B1    = exp(-(11/Male_lambda_B1)^shape_male_B1),
    Male_12_B1    = exp(-(12/Male_lambda_B1)^shape_male_B1),
    Male_13_B1    = exp(-(13/Male_lambda_B1)^shape_male_B1),
    Male_14_B1    = exp(-(14/Male_lambda_B1)^shape_male_B1),
    Male_15_B1    = exp(-(15/Male_lambda_B1)^shape_male_B1),
    Male_16_B1    = exp(-(16/Male_lambda_B1)^shape_male_B1),
    Male_17_B1    = exp(-(17/Male_lambda_B1)^shape_male_B1),
    Male_18_B1    = exp(-(18/Male_lambda_B1)^shape_male_B1),
    Male_19_B1    = exp(-(19/Male_lambda_B1)^shape_male_B1),
    Male_20_B1    = exp(-(20/Male_lambda_B1)^shape_male_B1),
    Male_21_B1 = exp(-(21/Male_lambda_B1)^shape_male_B1),
    Male_22_B1 = exp(-(22/Male_lambda_B1)^shape_male_B1),
    Male_23_B1 = exp(-(23/Male_lambda_B1)^shape_male_B1),
    Male_24_B1 = exp(-(24/Male_lambda_B1)^shape_male_B1),
    Male_25_B1 = exp(-(25/Male_lambda_B1)^shape_male_B1),
    Male_26_B1 = exp(-(26/Male_lambda_B1)^shape_male_B1),
    Male_27_B1 = exp(-(27/Male_lambda_B1)^shape_male_B1),
    Male_28_B1 = exp(-(28/Male_lambda_B1)^shape_male_B1),
    Male_29_B1 = exp(-(29/Male_lambda_B1)^shape_male_B1),
    # Block 2
    Control_0_B2  = exp(-(0/Control_lambda_B2)^shape_control_B2),  
    Control_1_B2  = exp(-(1/Control_lambda_B2)^shape_control_B2),
    Control_2_B2  = exp(-(2/Control_lambda_B2)^shape_control_B2),
    Control_3_B2  = exp(-(3/Control_lambda_B2)^shape_control_B2),
    Control_4_B2  = exp(-(4/Control_lambda_B2)^shape_control_B2),
    Control_5_B2  = exp(-(5/Control_lambda_B2)^shape_control_B2),
    Control_6_B2  = exp(-(6/Control_lambda_B2)^shape_control_B2),
    Control_7_B2  = exp(-(7/Control_lambda_B2)^shape_control_B2),
    Control_8_B2 = exp(-(8/Control_lambda_B2)^shape_control_B2),
    Control_9_B2 = exp(-(9/Control_lambda_B2)^shape_control_B2),
    Control_10_B2 = exp(-(10/Control_lambda_B2)^shape_control_B2),
    Control_11_B2 = exp(-(11/Control_lambda_B2)^shape_control_B2),
    Control_12_B2 = exp(-(12/Control_lambda_B2)^shape_control_B2),
    Control_13_B2 = exp(-(13/Control_lambda_B2)^shape_control_B2),
    Control_14_B2 = exp(-(14/Control_lambda_B2)^shape_control_B2),
    Control_15_B2 = exp(-(15/Control_lambda_B2)^shape_control_B2),
    Control_16_B2 = exp(-(16/Control_lambda_B2)^shape_control_B2),
    Control_17_B2 = exp(-(17/Control_lambda_B2)^shape_control_B2),
    Control_18_B2 = exp(-(18/Control_lambda_B2)^shape_control_B2),
    Control_19_B2 = exp(-(19/Control_lambda_B2)^shape_control_B2),
    Control_20_B2 = exp(-(20/Control_lambda_B2)^shape_control_B2),
    Control_21_B2 = exp(-(21/Control_lambda_B2)^shape_control_B2),
    Control_22_B2 = exp(-(22/Control_lambda_B2)^shape_control_B2),
    Control_23_B2 = exp(-(23/Control_lambda_B2)^shape_control_B2),
    Control_24_B2 = exp(-(24/Control_lambda_B2)^shape_control_B2),
    Control_25_B2 = exp(-(25/Control_lambda_B2)^shape_control_B2),
    Control_26_B2 = exp(-(26/Control_lambda_B2)^shape_control_B2),
    Control_27_B2 = exp(-(27/Control_lambda_B2)^shape_control_B2),
    Control_28_B2 = exp(-(28/Control_lambda_B2)^shape_control_B2),
    Control_29_B2 = exp(-(29/Control_lambda_B2)^shape_control_B2),
    Female_0_B2  = exp(-(0/Female_lambda_B2)^shape_female_B2),
    Female_1_B2  = exp(-(1/Female_lambda_B2)^shape_female_B2),
    Female_2_B2  = exp(-(2/Female_lambda_B2)^shape_female_B2),
    Female_3_B2  = exp(-(3/Female_lambda_B2)^shape_female_B2),
    Female_4_B2  = exp(-(4/Female_lambda_B2)^shape_female_B2),
    Female_5_B2  = exp(-(5/Female_lambda_B2)^shape_female_B2),
    Female_6_B2  = exp(-(6/Female_lambda_B2)^shape_female_B2),
    Female_7_B2  = exp(-(7/Female_lambda_B2)^shape_female_B2),
    Female_8_B2  = exp(-(8/Female_lambda_B2)^shape_female_B2),
    Female_9_B2  = exp(-(9/Female_lambda_B2)^shape_female_B2),
    Female_10_B2  = exp(-(10/Female_lambda_B2)^shape_female_B2),
    Female_11_B2  = exp(-(11/Female_lambda_B2)^shape_female_B2),
    Female_12_B2  = exp(-(12/Female_lambda_B2)^shape_female_B2),
    Female_13_B2  = exp(-(13/Female_lambda_B2)^shape_female_B2),
    Female_14_B2  = exp(-(14/Female_lambda_B2)^shape_female_B2),
    Female_15_B2  = exp(-(15/Female_lambda_B2)^shape_female_B2),
    Female_16_B2  = exp(-(16/Female_lambda_B2)^shape_female_B2),
    Female_17_B2  = exp(-(17/Female_lambda_B2)^shape_female_B2),
    Female_18_B2  = exp(-(18/Female_lambda_B2)^shape_female_B2),
    Female_19_B2  = exp(-(19/Female_lambda_B2)^shape_female_B2),
    Female_20_B2  = exp(-(20/Female_lambda_B2)^shape_female_B2),
    Female_21_B2 = exp(-(21/Female_lambda_B2)^shape_female_B2),
    Female_22_B2 = exp(-(22/Female_lambda_B2)^shape_female_B2),
    Female_23_B2 = exp(-(23/Female_lambda_B2)^shape_female_B2),
    Female_24_B2 = exp(-(24/Female_lambda_B2)^shape_female_B2),
    Female_25_B2 = exp(-(25/Female_lambda_B2)^shape_female_B2),
    Female_26_B2 = exp(-(26/Female_lambda_B2)^shape_female_B2),
    Female_27_B2 = exp(-(27/Female_lambda_B2)^shape_female_B2),
    Female_28_B2 = exp(-(28/Female_lambda_B2)^shape_female_B2),
    Female_29_B2 = exp(-(29/Female_lambda_B2)^shape_female_B2),
    Male_0_B2     = exp(-(0/Male_lambda_B2)^shape_male_B2),
    Male_1_B2     = exp(-(1/Male_lambda_B2)^shape_male_B2),
    Male_2_B2     = exp(-(2/Male_lambda_B2)^shape_male_B2),
    Male_3_B2     = exp(-(3/Male_lambda_B2)^shape_male_B2),
    Male_4_B2     = exp(-(4/Male_lambda_B2)^shape_male_B2),
    Male_5_B2     = exp(-(5/Male_lambda_B2)^shape_male_B2),
    Male_6_B2     = exp(-(6/Male_lambda_B2)^shape_male_B2),
    Male_7_B2     = exp(-(7/Male_lambda_B2)^shape_male_B2),
    Male_8_B2     = exp(-(8/Male_lambda_B2)^shape_male_B2),
    Male_9_B2     = exp(-(9/Male_lambda_B2)^shape_male_B2),
    Male_10_B2    = exp(-(10/Male_lambda_B2)^shape_male_B2),
    Male_11_B2    = exp(-(11/Male_lambda_B2)^shape_male_B2),
    Male_12_B2    = exp(-(12/Male_lambda_B2)^shape_male_B2),
    Male_13_B2    = exp(-(13/Male_lambda_B2)^shape_male_B2),
    Male_14_B2    = exp(-(14/Male_lambda_B2)^shape_male_B2),
    Male_15_B2    = exp(-(15/Male_lambda_B2)^shape_male_B2),
    Male_16_B2    = exp(-(16/Male_lambda_B2)^shape_male_B2),
    Male_17_B2    = exp(-(17/Male_lambda_B2)^shape_male_B2),
    Male_18_B2    = exp(-(18/Male_lambda_B2)^shape_male_B2),
    Male_19_B2    = exp(-(19/Male_lambda_B2)^shape_male_B2),
    Male_20_B2    = exp(-(20/Male_lambda_B2)^shape_male_B2),
    Male_21_B2 = exp(-(21/Male_lambda_B2)^shape_male_B2),
    Male_22_B2 = exp(-(22/Male_lambda_B2)^shape_male_B2),
    Male_23_B2 = exp(-(23/Male_lambda_B2)^shape_male_B2),
    Male_24_B2 = exp(-(24/Male_lambda_B2)^shape_male_B2),
    Male_25_B2 = exp(-(25/Male_lambda_B2)^shape_male_B2),
    Male_26_B2 = exp(-(26/Male_lambda_B2)^shape_male_B2),
    Male_27_B2 = exp(-(27/Male_lambda_B2)^shape_male_B2),
    Male_28_B2 = exp(-(28/Male_lambda_B2)^shape_male_B2),
    Male_29_B2 = exp(-(29/Male_lambda_B2)^shape_male_B2)) %>% 
  select(-c(contains(c("shape", "lambda"))))

Weibull_extinction_estimates_long <-
  Weibull_survival_curve %>% 
  pivot_longer(cols = everything(), names_to = "Evolution treatment", values_to = "Prop_lineages_surviving") %>% 
  separate(`Evolution treatment`, into = c("Evolution treatment", "Generation", "Block"), sep = "_") %>% 
    mutate(`Evolution treatment` = case_when(
    `Evolution treatment` == "Female" ~ "Female-limited",
    `Evolution treatment` == "Male" ~ "Male-limited",
    `Evolution treatment` == "Control" ~ "Control"
  ))

\(~\)

Create Figure 1

Make panel a of Figure 1

# Block 1

weibull_surv_plot_B1 <- 
  Weibull_extinction_estimates_long %>% 
  filter(Block == "B1") %>% 
  group_by(`Evolution treatment`, Generation) %>% 
  tidybayes::median_qi(Prop_lineages_surviving, .width = 0.5) %>% 
  mutate(Generation = as.numeric(Generation)) %>% 
  arrange(Generation) %>% 
  # plot!
  ggplot(aes(x = Generation)) +
  geom_ribbon(aes(ymin = .lower, ymax = .upper, fill = `Evolution treatment`),
              alpha = 1/2) +
  geom_line(aes(y = Prop_lineages_surviving, color = `Evolution treatment`), linetype =5, linewidth = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  scale_color_manual(values = met.brewer("Hiroshige", 3), guide = "none") +
  scale_x_continuous(breaks = c(0, 5, 10, 15, 20, 25, 30)) +
  scale_y_continuous(breaks = c(0, 0.25, .5, 0.75, 1), limits = 0:1) +
  labs(x = "Generations of inbreeding", y = "Proportion of surving lineages", fill = "Selection response\nhistory") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.background = element_rect(fill='transparent'), #transparent legend bg
        legend.box.background = element_rect(fill='transparent', colour = 'transparent'), #transparent legend panel
        legend.position = c(.95, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(6, 6, 6, 6),
        text = element_text(size = 14),
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 11))

We can also plot the mean generations until extinction for each evolution treatment. Some data wrangling is first needed.

new_data <- expand_grid(
  Evolution_treatment = extinction_data_wrangled$Evolution_treatment,
  Block = 1:2) %>% 
  distinct(Evolution_treatment, Block) %>%
  mutate(key = paste("V", 1:n(), sep = ""))

weibull_estimates <- 
  fitted(extinction_model_sm, newdata = new_data,
         re_formula = NA, summary = F) %>% 
  as_tibble() %>% 
  rename(`Female-limited_1` = V1, `Female-limited_2` = V2, `Male-limited_1` = V3, `Male-limited_2` = V4, Control_1 = V5, Control_2 = V6)

mean_weibull_estimates <- 
  weibull_estimates %>% 
  pivot_longer(cols = 1:6, names_to = "Evolution treatment", values_to = "generations") %>% 
  separate(col = `Evolution treatment`, into = c("Evolution treatment", "Block"), sep = "_")


# calculate contrasts

weibull_contrasts_B1 <-
  weibull_estimates %>% 
  mutate(`Female - Control` = `Female-limited_1` - Control_1,
         `Male - Female` = `Male-limited_1` - `Female-limited_1`,
         `Male - Control` = `Male-limited_1` - Control_1) %>% 
  select(-c(`Male-limited_1`, Control_1, `Female-limited_1`,
            `Male-limited_2`, Control_2, `Female-limited_2`)) %>% 
  pivot_longer(cols = 1:3, names_to = "Contrast", values_to = "generation_diff")

weibull_contrasts_B2 <-
  weibull_estimates %>% 
  mutate(`Female - Control` = `Female-limited_2` - Control_2,
         `Male - Female` = `Male-limited_2` - `Female-limited_2`,
         `Male - Control` = `Male-limited_2` - Control_2) %>% 
  select(-c(`Male-limited_1`, Control_1, `Female-limited_1`,
            `Male-limited_2`, Control_2, `Female-limited_2`)) %>% 
  pivot_longer(cols = 1:3, names_to = "Contrast", values_to = "generation_diff")

Create panels b and c of Figure 1

# plot the means

# block 1

ext_p1_B1 <- 
  mean_weibull_estimates %>% 
  filter(Block == "1") %>% 
  ggplot(aes(x = generations, y = `Evolution treatment`)) +
  stat_halfeye(aes(fill = `Evolution treatment`), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) + # width indicates the uncertainty intervals: here we have 66% and 95% intervals + # width indicates the uncertainty intervals: here we have 66% and 95% intervals+
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x = "Mean generations till extinction", y = "Selection response history") +
  scale_x_continuous(breaks=seq(4, 12, 1)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(), 
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

# plot the contrasts

ext_p2_B1 <- 
  weibull_contrasts_B1 %>% 
  ggplot(aes(x = generation_diff, y = fct_relevel(Contrast, "Female - Control", "Male - Female", "Male - Control"))) +
  stat_halfeye(aes(fill = Contrast), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) + 
  scale_fill_manual(values = c(carto_pal(7, "Peach")[2], carto_pal(7, "Purp")[1], carto_pal(7, "TealGrn")[1])) +
  geom_vline(xintercept = 0, linetype = 2, colour = "black", size = 1) +
  labs(x = "Diff. in generations till extinction", y = "Treatment contrast") +
  scale_x_continuous(breaks=seq(-4, 6, 2)) +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        panel.grid.minor.x = element_blank(),
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

We can also estimate the difference between evolutionary treatments in the proportion of lineages extant in each generation. Below we calculate each contrast and make panels d, e and f

# Block 1

Difference_gens_B1 <-
  Weibull_survival_curve %>% 
  select(contains("B1")) %>% 
  mutate(G1_diff.c = Male_1_B1 - Control_1_B1,
         G1_diff.f = Male_1_B1 - Female_1_B1,
         G1_diff.fc = Female_1_B1 - Control_1_B1,
         G2_diff.c = Male_2_B1 - Control_2_B1,
         G2_diff.f = Male_2_B1 - Female_2_B1,
         G2_diff.fc = Female_2_B1 - Control_2_B1,
         G3_diff.c = Male_3_B1 - Control_3_B1,
         G3_diff.f = Male_3_B1 - Female_3_B1,
         G3_diff.fc = Female_3_B1 - Control_3_B1,
         G4_diff.c = Male_4_B1 - Control_4_B1,
         G4_diff.f = Male_4_B1 - Female_4_B1,
         G4_diff.fc = Female_4_B1 - Control_4_B1,
         G5_diff.c = Male_5_B1 - Control_5_B1,
         G5_diff.f = Male_5_B1 - Female_5_B1,
         G5_diff.fc = Female_5_B1 - Control_5_B1,
         G6_diff.c = Male_6_B1 - Control_6_B1,
         G6_diff.f = Male_6_B1 - Female_6_B1,
         G6_diff.fc = Female_6_B1 - Control_6_B1,
         G7_diff.c = Male_7_B1 - Control_7_B1,
         G7_diff.f = Male_7_B1 - Female_7_B1,
         G7_diff.fc = Female_7_B1 - Control_7_B1,
         G8_diff.c = Male_8_B1 - Control_8_B1,
         G8_diff.f = Male_8_B1 - Female_8_B1,
         G8_diff.fc = Female_8_B1 - Control_8_B1,
         G9_diff.c = Male_9_B1 - Control_9_B1,
         G9_diff.f = Male_9_B1 - Female_9_B1,
         G9_diff.fc = Female_9_B1 - Control_9_B1,
         G10_diff.c = Male_10_B1 - Control_10_B1,
         G10_diff.f = Male_10_B1 - Female_10_B1,
         G10_diff.fc = Female_10_B1 - Control_10_B1,
         G11_diff.c = Male_11_B1 - Control_11_B1,
         G11_diff.f = Male_11_B1 - Female_11_B1,
         G11_diff.fc = Female_11_B1 - Control_11_B1,
         G12_diff.c = Male_12_B1 - Control_12_B1,
         G12_diff.f = Male_12_B1 - Female_12_B1,
         G12_diff.fc = Female_12_B1 - Control_12_B1,
         G13_diff.c = Male_13_B1 - Control_13_B1,
         G13_diff.f = Male_13_B1 - Female_13_B1,
         G13_diff.fc = Female_13_B1 - Control_13_B1,
         G14_diff.c = Male_14_B1 - Control_14_B1,
         G14_diff.f = Male_14_B1 - Female_14_B1,
         G14_diff.fc = Female_14_B1 - Control_14_B1,
         G15_diff.c = Male_15_B1 - Control_15_B1,
         G15_diff.f = Male_15_B1 - Female_15_B1,
         G15_diff.fc = Female_15_B1 - Control_15_B1,
         G16_diff.c = Male_16_B1 - Control_16_B1,
         G16_diff.f = Male_16_B1 - Female_16_B1,
         G16_diff.fc = Female_16_B1 - Control_16_B1,
         G17_diff.c = Male_17_B1 - Control_17_B1,
         G17_diff.f = Male_17_B1 - Female_17_B1,
         G17_diff.fc = Female_17_B1 - Control_17_B1,
         G18_diff.c = Male_18_B1 - Control_18_B1,
         G18_diff.f = Male_18_B1 - Female_18_B1,
         G18_diff.fc = Female_18_B1 - Control_18_B1,
         G19_diff.c = Male_19_B1 - Control_19_B1,
         G19_diff.f = Male_19_B1 - Female_19_B1,
         G19_diff.fc = Female_19_B1 - Control_19_B1,
         G20_diff.c = Male_20_B1 - Control_20_B1,
         G20_diff.f = Male_20_B1 - Female_20_B1,
         G20_diff.fc = Female_20_B1 - Control_20_B1,
         G21_diff.c = Male_21_B1 - Control_21_B1,
         G21_diff.f = Male_21_B1 - Female_21_B1,
         G21_diff.fc = Female_21_B1 - Control_21_B1,
         G22_diff.c = Male_22_B1 - Control_22_B1,
         G22_diff.f = Male_22_B1 - Female_22_B1,
         G22_diff.fc = Female_22_B1 - Control_22_B1,
         G23_diff.c = Male_23_B1 - Control_23_B1,
         G23_diff.f = Male_23_B1 - Female_23_B1,
         G23_diff.fc = Female_23_B1 - Control_23_B1,
         G24_diff.c = Male_24_B1 - Control_24_B1,
         G24_diff.f = Male_24_B1 - Female_24_B1,
         G24_diff.fc = Female_24_B1 - Control_24_B1,
         G25_diff.c = Male_25_B1 - Control_25_B1,
         G25_diff.f = Male_25_B1 - Female_25_B1,
         G25_diff.fc = Female_25_B1 - Control_25_B1,
         G26_diff.c = Male_26_B1 - Control_26_B1,
         G26_diff.f = Male_26_B1 - Female_26_B1,
         G26_diff.fc = Female_26_B1 - Control_26_B1,
         G27_diff.c = Male_27_B1 - Control_27_B1,
         G27_diff.f = Male_27_B1 - Female_27_B1,
         G27_diff.fc = Female_27_B1 - Control_27_B1,
         G28_diff.c = Male_28_B1 - Control_28_B1,
         G28_diff.f = Male_28_B1 - Female_28_B1,
         G28_diff.fc = Female_28_B1 - Control_28_B1,
         G29_diff.c = Male_2_B1 - Control_29_B1,
         G29_diff.f = Male_29_B1 - Female_29_B1,
         G29_diff.fc = Female_29_B1 - Control_29_B1) %>% 
  select(starts_with("G")) %>% 
  pivot_longer(cols = everything(), names_to = "Difference contrast", values_to = "survival_diff") %>% 
  separate(`Difference contrast`, into = c("Generation", "Difference contrast"), sep = "_") %>% 
  mutate(Generation = as.numeric(str_remove(Generation, "G")))


# Make the three plots

Leaf_plot_mc_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.c") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Purp") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Control\nProp. surv lineages",
       y = "Generation of inbreeding") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8)) 

Leaf_plot_mf_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.f") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "TealGrn") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Female\nProp. surv lineages",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_fc_B1 <-
  Difference_gens_B1 %>%
  filter(`Difference contrast` == "diff.fc") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Peach") +
  coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Female - Control\nProp. surv lineages",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Combine the 6 panels

(weibull_surv_plot_B1 / (ext_p1_B1 + ext_p2_B1)) / (Leaf_plot_mc_B1 + Leaf_plot_mf_B1 + Leaf_plot_fc_B1) +
  plot_annotation(tag_levels = 'a')

Figure 1. …

\(~\)

The plot displays an interesting pattern, where the extinction curves for each evolution treatment converge upon one another in the later generations of the experiment. Single pair, full sibling inbreeding is expected to reduce genome-wide heterozygosity to 0.1% of original levels after 10 generations i.e. \(100*\frac{1}{2}^{10}\) (except at loci where selection against lethal recessive alleles actively stops homozygosity from occurring). Even very strong selection shall reduce the equilibrium point at which mutation-selection balance occurs (especially for recessive alleles) and it may be that in a fully homozygous state, mutation load is relatively similar across evolution treatments. The shape parameter suggests that lineages carrying male-limited autosomes suffer fewer extinction events during the ‘active’ inbreeding phase than the other two treatments, then suffer a proportionally similar amount once inbreeding ceases to increase homozygosity. This may be because extinction becomes more environmentally driven or due to new mutations (the latter is unlikely) past this point, processes which we expect to affect all lineages in a similar way.

\(~\)

Productivity analysis

\(~\)

We have several hypotheses that we test with the productivity data. First, productivity should be negatively correlated with the number of generations inbreeding occurs, due to inbreeding depression. As mentioned above, this effect should be strongest in the first ~8-10 generations of the experiment, during which full-sibling inbreeding should have appreciable effects on genome wide heterozygosity. After this point, the % of heterozygosity across the genome should very small. Hence, each lineage does not get much more inbred past this point, and we expect productivity to stabilise, assuming the lineage is still extant. Second, lineages carrying autosomes that have responded to selection on males should exhibit a smaller drop in productivity compared with lineages caryring the female-adapted or control autosomes, because they have a history of stronger selection that should, in theory, have purged the genome of recessive deleterious alleles.

Load in the data

data <-
  read_csv("Data/Productivity_data.csv")

Productivity_data <- 
  left_join(
    data,
    
    data %>% 
      distinct(Cross, Replicate) %>% 
      rowid_to_column("Lineage")
  ) %>% 
  select(Lineage, everything()) %>% 
  mutate(across(1:7, as.factor),
         Collection_window_offspring = Female_offspring + Male_offspring,
         Pre_window_offspring = Pre_window_female_offspring + Pre_window_male_offspring,
         Total_female_offspring = Female_offspring + Pre_window_female_offspring,
         Total_male_offspring = Male_offspring + Pre_window_male_offspring,
         Total_offspring = Total_female_offspring + Total_male_offspring) %>% 
  # In one generation of the experiment (b1 = G24 & B2 = G15) sibling pairs were setup a day early and removed from their vials at the regular time, meaning that they had an extra day to produce offspring. To correct for this we multiply offspring counts by 0.75.
  mutate(Collection_window_offspring = if_else(Count_conditions == "Extra day", 
                                               round(Collection_window_offspring * 0.75),  Collection_window_offspring),
         # note that because everything is moved a day early, pre-window offspring counts will still be inflated even after this correction
         Pre_window_offspring = if_else(Count_conditions == "Extra day", 
                                               round(Pre_window_offspring * 0.75),  Pre_window_offspring))
  
# Make a tibble that only includes data from the first 20 generations of the experiment (Block 1 ran for 29 gens, while Block 2 ran for 20). Then remove lineage's that at some point were lost because of handling errors and thus do not have data from that generation onwards.

Productivity_data_clean <-
  left_join(
    Productivity_data %>% 
      filter(Generation < 21) %>% 
      filter(Collection_window_offspring != "NA") %>% # remove NA values
      group_by(Lineage, Block) %>% # these remaining lines remove lineage's that had an NA value 
      count() %>% 
      ungroup() %>% 
      filter(n == 20), # remove lineage's that have NA values for productivity in at least one generation
    
    Productivity_data) %>% 
  filter(Generation < 21) # only include data collected on the first 20 generations of inbreeding (block 2's endpoint)

# We also include a dataframe that removes lineages that are extinct. This means that 0 values are far less prevalent. We can use the `extinction_data_wrangled$Gens_to_extinct` column to help us here. 

Productivity_data_trimmed_extant <-
  left_join(
    Productivity_data_clean,  
    extinction_data_wrangled %>% 
      select(Lineage, Gens_to_extinct)
  ) %>% 
  mutate(Extinct = if_else(Generation > Gens_to_extinct, "Yes", "No")) %>% 
  filter(Extinct == "No")

Do we observe inbreeding depression?

Let’s plot the raw data to get an idea.

# Collection window plot

point_plot_1 <-
  Productivity_data_clean %>%
  ggplot(aes(x = Generation, y = Collection_window_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.25) +
  geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7]) +
  geom_smooth(data = Productivity_data_trimmed_extant, size = 1.5, colour = met.brewer("OKeeffe2")[6]) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20)) +
  labs(y = "Collection window\noffspring production", x = "Generation of inbreeding") +
  theme(text = element_text(size = 14))

# Total productivity plot

point_plot_2 <-
  Productivity_data %>% 
  ggplot(aes(x = Generation, y = Total_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.25) +
  geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7]) +
  geom_smooth(data = Productivity_data_trimmed_extant, size = 1.5, colour = met.brewer("OKeeffe2")[6]) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20)) +
  labs(y = "Total offspring production", x = "Generation of inbreeding") +
  theme(text = element_text(size = 14))

point_plot_1 / point_plot_2

\(~\)

Testing for our casual effect

Modelling approach

As mentioned above, we have strong expectations for how full-sibling inbreeding should affect productivity. A halving of genome-wide heterozygosity and the expression of recessive deleterious alleles that comes with this should follow a pattern of exponential decay. This non-linear process can be modelled using the brms non-linear syntax.

Here we model the productivity at generation \(t\) via the function \(a - e^{\lambda t}\) where \(a\) and \(\lambda\) are parameters that control the initial productivity and the rate of its decay as generations of inbreeding progress. We force \(a\) to be positive using the exp() function, which expresses it on the exponential scale. Large \(a\) indicates higher starting productivity at generation 0 (we started observation at generation 1, the productivity for which is given by \(a - e^{\lambda}\)). Positive values of \(\lambda\) indicate that productivity declines with inbreeding, which is our strong expectation and clearly the case following inspection of the raw data (see Figure SX).

We model inbreeding depression while including zero values for all rows where a lineage was extinct. This helps combat underestimation of the decay parameter, caused by the non-random extinction of lineages, where high fitness lineages become over-represented as the generations of inbreeding progress (i.e. selection).

Fixed and random effects

In the brms non-linear syntax, different formulas can be fit for each parameter. We fit the same fixed effects for \(a\) and \(\lambda\): Evolution treatment and Block. We fit ‘Lineage’ as a random effect to account for repeated measurements taken on each lineage for \(a\), but are unable to do this for \(\lambda\), as individual lineage productivity curves are highly heteroskedastic, and are skewed by extinction events. To minimise pseudoreplication for \(\lambda\), we fit Cross as a random effect (currently only on \(\lambda\)), as we do for the extinction data.

\(~\)

Simulate the curve, with the priors we will specify

n <- 1e4

# define the x-axis breaks
at <- 1:20

# how many prior draws would you like?
n_draws <- 200

# simulate
set.seed(16)

prior <-
  tibble(index = 1:n,
         a   = rnorm(n, mean = 4.5, sd = 0.5),
         lambda     = rnorm(n, mean = 0.2, sd = 0.1)) %>% 
  slice_sample(n = n_draws) %>% 
  expand(nesting(index, a, lambda),
         Generation = seq(from = 0, to = 20, length.out = 1e2)) %>% 
  mutate(productivity = exp(a - lambda * Generation)) 


prior %>% 
  ggplot(aes(x = Generation, y = productivity, group = index)) +
  geom_line(size = 1/2, alpha = 1/4, colour = met.brewer("Hiroshige")[2]) +
  theme_tidybayes() +
  scale_y_continuous(limits = c(0,300), expand = expansion(mult = c(0, .1))) +
  scale_x_continuous(limits = c(0,20), expand = c(0, 0)) +
  labs(y = "Lineage productivity", x = "Generation of inbreeding") +
  theme(text = element_text(size = 14))

Figure XX: Prior predictive simulation for the productivity decline model. The plot shows the results from 100 prior draws.

Fit the non-linear model

nonlinear_productivity <- 
  brm(bf(Collection_window_offspring ~ exp(a - (lambda * Generation)),
         a ~ 0 + Treatment * Block + (1|Lineage), 
         lambda ~ 0 + Treatment * Block + (1|Cross), 
         nl = TRUE),
      data = Productivity_data_clean,
      family = negbinomial(link = "identity"),
      prior = c(prior(normal(4.5, 0.5), class = b, coef = TreatmentControl, nlpar = "a"),
                prior(normal(4.5, 0.5), class = b, coef = TreatmentFemale, nlpar = "a"),
                prior(normal(4.5, 0.5), class = b, coef = TreatmentMale, nlpar = "a"),
                prior(normal(0, 0.5), class = b, coef = Block2, nlpar = "a"),
                prior(normal(0.2, 0.1), class = b, coef = TreatmentControl, nlpar = "lambda"),
                prior(normal(0.2, 0.1), class = b, coef = TreatmentFemale, nlpar = "lambda"),
                prior(normal(0.2, 0.1), class = b, coef = TreatmentMale, nlpar = "lambda"),
                prior(normal(0, 0.1), class = b, coef = Block2, nlpar = "lambda"),
                prior(gamma(3, 1.5), class = sd, nlpar = "a"),
                prior(gamma(0.1, 2), class = sd, nlpar = "lambda")),
      control = list(adapt_delta = 0.8, max_treedepth = 15), seed = 1,
      iter = 30000, warmup = 5000, chains = 4, cores = 4,
      file = "Fits/non_linear_productivity_model_2")

How does our curve fit the data

new_data <- 
  Productivity_data_clean %>% 
  select(Generation, Treatment, Block) %>%
  distinct() %>%
  mutate(key = paste("V", 1:n(), sep = ""))

preds <- as.data.frame(fitted(nonlinear_productivity, newdata = new_data, re_formula = NA, summary=F)) %>% 
  mutate(draw = 1:n()) %>% 
  gather(key, Collection_window_offspring, -draw) %>% 
  as_tibble() %>% 
  left_join(new_data, by = "key") %>% 
  select(-key) %>% 
    mutate(Treatment = case_when(
    Treatment == "Female" ~ "Female-limited",
    Treatment == "Male" ~ "Male-limited",
    Treatment == "Control" ~ "Control"))

preds_summary <-
  preds %>% 
  group_by(Treatment, Generation, Block) %>%
  median_qi(Collection_window_offspring, .width = 0.5)

nl_p1 <-
  Productivity_data_clean %>% 
  filter(Block == 1) %>%  
  ggplot(aes(x = Generation, y = Collection_window_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.2) +
 # geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7], alpha = 0.4) +
  geom_ribbon(data = preds_summary %>% filter(Block == "1"), 
             aes(ymin = .lower, ymax = .upper, fill = Treatment), alpha = 1/2) +
  geom_line(aes(group = Treatment, colour = Treatment), data = preds_summary %>% filter(Block == 1),
            size = 1, alpha = 1, linetype = 5) +
  scale_linetype_manual(values = c(1, 2, 3)) +
  scale_colour_manual(values = met.brewer("Hiroshige", 3), guide = "none") +
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  scale_y_continuous(expand = expansion(mult = c(0.01, 0))) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20), ylim = c(0, 150)) +
  labs(y = "Lineage productivity", x = "Generation of inbreeding", fill = "Selection response\nhistory") +
  theme(text = element_text(size = 14),
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 11),
        legend.position = c(.99, .99),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(6, 6, 6, 6))

nl_p2 <-
  Productivity_data_clean %>% filter(Block == 2) %>% 
  ggplot(aes(x = Generation, y = Collection_window_offspring)) +
  geom_jitter(colour = met.brewer("OKeeffe2")[2], width = 0.25, 
              shape = 1.5, stroke =2, size = 1.2, alpha = 0.2) +
  # geom_smooth(size = 1.5, colour = met.brewer("OKeeffe2")[7], alpha = 0.4) +
  geom_ribbon(data = preds_summary %>% filter(Block == 2), 
              aes(ymin = .lower, ymax = .upper, fill = Treatment), alpha = 1/2) +
  geom_line(aes(group = Treatment, colour = Treatment), data = preds_summary %>% filter(Block == 2),
            size = 1, alpha = 1, linetype = 5) +
  scale_linetype_manual(values = c(1, 2, 3)) +
  scale_colour_manual(values = met.brewer("Hiroshige", 3), guide = "none") +
  scale_y_continuous(expand = expansion(mult = c(0.01, 0))) +
  scale_fill_manual(values = met.brewer("Hiroshige", 3)) +
  theme_tidybayes() +
  coord_cartesian(xlim = c(1, 20), ylim = c(0, 150)) +
  labs(y = "Lineage productivity", x = "Generation of inbreeding", subtitle = "Block 2", fill = "Selection response\nhistory") +
  theme(text = element_text(size = 14),
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 11),
        legend.position = c(.99, .99),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(6, 6, 6, 6))

\(~\)

Estimating \(a\) and \(\lambda\)

Initial_productivity_estimates <-
as_draws_df(nonlinear_productivity, variable = "^b_a", regex = TRUE) %>% 
  mutate(`Female-limited B1` = b_a_TreatmentFemale,
         `Male-limited B1` = b_a_TreatmentMale,
         `Control B1` = b_a_TreatmentControl,
         `Female-limited B2` = b_a_TreatmentFemale + b_a_Block2 + `b_a_TreatmentFemale:Block2`,
         `Male-limited B2` = b_a_TreatmentMale + b_a_Block2 + `b_a_TreatmentMale:Block2`,
         `Control B2` = b_a_TreatmentControl + b_a_Block2) %>%
  select(`Female-limited B1`, `Male-limited B1`, `Control B1`,
         `Female-limited B2`, `Male-limited B2`, `Control B2`) %>% 
  mutate_all(~ exp(.x)) %>% 
  mutate(posterior_sample = 1:n()) %>% 
  gather(Evolution_treatment, a, -posterior_sample) %>% 
  separate(col = Evolution_treatment, sep = " ", into = c("Evolution_treatment", "Block"))
  

Initial_productivity_plot_B1 <-
  Initial_productivity_estimates %>% 
  filter(Block == "B1") %>%
  
  ggplot(aes(x = a, y = Evolution_treatment)) +
  stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) + 
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  coord_cartesian(xlim = c(50, 150)) +
  labs(x=expression(paste("Initial productivity parameter ",italic("a"))), y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))


Initial_productivity_plot_B2 <-
  Initial_productivity_estimates %>% 
  filter(Block == "B2") %>%
  
  ggplot(aes(x = a, y = Evolution_treatment)) +
  stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x=expression(paste("Initial productivity parameter ",italic("a"))), y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))


decay_estimates <-  
  as_draws_df(nonlinear_productivity, variable = "^b_lambda", regex = TRUE) %>% 
  mutate(`Female-limited B1` = b_lambda_TreatmentFemale,
         `Male-limited B1` = b_lambda_TreatmentMale,
         `Control B1` = b_lambda_TreatmentControl,
         `Female-limited B2` = b_lambda_TreatmentFemale + b_lambda_Block2 + `b_lambda_TreatmentFemale:Block2`,
         `Male-limited B2` = b_lambda_TreatmentMale + b_lambda_Block2 + `b_lambda_TreatmentMale:Block2`,
         `Control B2` = b_lambda_TreatmentControl + b_lambda_Block2) %>%
 select(`Female-limited B1`, `Male-limited B1`, `Control B1`,
         `Female-limited B2`, `Male-limited B2`, `Control B2`) %>% 
  mutate(posterior_sample = 1:n()) %>% 
  gather(Evolution_treatment, lambda, -posterior_sample) %>%
  separate(col = Evolution_treatment, sep = " ", into = c("Evolution_treatment", "Block"))
  

decay_plot_B1 <-
  decay_estimates %>% 
  filter(Block == "B1") %>% 
  ggplot(aes(x = lambda, y = Evolution_treatment)) +
    stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white", 
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x=expression(paste("Decay rate parameter ", lambda,)), y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

decay_plot_B2 <-
  decay_estimates %>% 
  filter(Block == "B2") %>% 
  ggplot(aes(x = lambda, y = Evolution_treatment)) +
    stat_halfeye(aes(fill = Evolution_treatment), .width = c(0.66, 0.95), alpha = 1,
               point_interval = "mean_qi", point_fill = "white",
               shape = 21, point_size = 4, stroke = 1.5,
               slab_colour = "black", slab_size = 0.8) +
  scale_fill_manual(values = met.brewer("Hiroshige", 5)) +
  labs(x=expression(paste("Decay rate parameter ", lambda,)), y = "Selection response history") +
  theme_bw() + 
  theme(panel.background = element_rect(fill='transparent'), #transparent panel bg
        plot.background = element_rect(fill='transparent', color=NA), #transparent plot bg
        panel.grid.minor.x = element_blank(),
        legend.position = "none", #transparent legend panel
        text = element_text(size=14))

Create leaf plots like those in Figure 1

productivity_curve <-
  nonlinear_productivity %>% 
  as_draws_df() %>% 
  select(contains("b_")) %>% 
  mutate(across(1:3, ~ exp(.x)),
         Control_0  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*0),
         Control_1  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*1),
         Control_2  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*2),
         Control_3  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*3),
         Control_4  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*4),
         Control_5  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*5),
         Control_6  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*6),
         Control_7  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*7),
         Control_8  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*8),
         Control_9  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*9),
         Control_10  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*10),
         Control_11  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*11),
         Control_12  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*12),
         Control_13  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*13),
         Control_14  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*14),
         Control_15  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*15),
         Control_16  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*16),
         Control_17  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*17),
         Control_18  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*18),
         Control_19  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*19),
         Control_20  = b_a_TreatmentControl * exp(-(b_lambda_TreatmentControl)*20),
         Female_0  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*0),
         Female_1  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*1),
         Female_2  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*2),
         Female_3  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*3),
         Female_4  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*4),
         Female_5  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*5),
         Female_6  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*6),
         Female_7  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*7),
         Female_8  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*8),
         Female_9  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*9),
         Female_10  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*10),
         Female_11  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*11),
         Female_12  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*12),
         Female_13  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*13),
         Female_14  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*14),
         Female_15  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*15),
         Female_16  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*16),
         Female_17  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*17),
         Female_18  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*18),
         Female_19  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*19),
         Female_20  = b_a_TreatmentFemale * exp(-(b_lambda_TreatmentFemale)*20),
         Male_0  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*0),
         Male_1  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*1),
         Male_2  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*2),
         Male_3  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*3),
         Male_4  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*4),
         Male_5  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*5),
         Male_6  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*6),
         Male_7  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*7),
         Male_8  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*8),
         Male_9  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*9),
         Male_10  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*10),
         Male_11  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*11),
         Male_12  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*12),
         Male_13  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*13),
         Male_14  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*14),
         Male_15  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*15),
         Male_16  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*16),
         Male_17  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*17),
         Male_18  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*18),
         Male_19  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*19),
         Male_20  = b_a_TreatmentMale * exp(-(b_lambda_TreatmentMale)*20)) %>% 
  select(-c(contains("b_")))

Difference_gens_productivity <- 
  preds %>% 
  group_by(Generation, Treatment, Block) %>% 
  ungroup() %>% 
  pivot_wider(values_from = "Collection_window_offspring", names_from = "Treatment") %>% 
  mutate(diff.mc = `Male-limited` - Control,
         diff.mf = `Male-limited` - `Female-limited`,
         diff.fc = `Female-limited` - Control) %>% 
  select(Generation, Block, contains("diff")) %>% 
  pivot_longer(cols = contains("diff"), values_to = "survival_diff", names_to = "Difference contrast") 

# Make the three plots

Leaf_plot_mc_productivity_B1 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mc" & Block == "1") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Purp") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Control\nProductivity diff.",
       y = "Generation of inbreeding") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_mc_productivity_B2 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mc" & Block == "2") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Purp") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Control\nProductivity diff.",
       y = "Generation of inbreeding") +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_mf_productivity_B1 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mf" & Block == "1") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "TealGrn") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Female\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_mf_productivity_B2 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.mf" & Block == "2") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "TealGrn") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Male - Female\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_fc_productivity_B1 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.fc" & Block == "1") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Peach") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Female - Control\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Leaf_plot_fc_productivity_B2 <-
  Difference_gens_productivity %>%
  filter(`Difference contrast` == "diff.fc" & Block == "2") %>% 
  ggplot(aes(survival_diff, as.factor(Generation))) +
  stat_interval(.width = c(0.05, 0.66, 0.95), 
                height = 1, show.legend = F) +
  rcartocolor::scale_color_carto_d(palette = "Peach") +
  #coord_cartesian(xlim = c(-0.1, 0.3)) +
  scale_y_discrete(limits=rev) +
  geom_vline(linetype = 2, xintercept = 0, size = 1) +
  labs(x = "Female - Control\nProductivity diff.",
       y = NULL) +
  theme_bw() + 
  theme(legend.position = "none",
        panel.grid.minor = element_blank(),
        text = element_text(size=14),
        axis.text.y = element_text(size = 8))

Figure 2 and Figure SX

(nl_p1 / (Initial_productivity_plot_B1 + decay_plot_B1)) / (Leaf_plot_mc_productivity_B1 + Leaf_plot_mf_productivity_B1 + Leaf_plot_fc_productivity_B1) +
  plot_annotation(tag_levels = 'a')

Figure 2. the figure to end all figures again. Block 1

\(~\)

(nl_p2 / (Initial_productivity_plot_B2 + decay_plot_B2)) / (Leaf_plot_mc_productivity_B2 + Leaf_plot_mf_productivity_B2 + Leaf_plot_fc_productivity_B2) +
  plot_annotation(tag_levels = 'a')

Figure SX. the figure to end all figures again. Block 2

LS0tCnRpdGxlOiAiU2VsZWN0aW9uIGFtb25nIG1hbGVzIHJlZHVjZXMgbXV0YXRpb24gbG9hZCIKYXV0aG9yOiAiVGhvbWFzIEtlYW5leSwgSGVpZGkgV29uZywgWGlhbWVuZyBRaSwgVGhlcmVzYSBKb25lcyBhbmQgTHVrZSBIb2xtYW4iCiNiaWJsaW9ncmFwaHk6ICJzdXBwX3JlZmVyZW5jZXMuYmliIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgZGVwdGg6IDEKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRoZW1lOiB5ZXRpCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBGQUxTRSkKYGBgCgojIExvYWQgcGFja2FnZXMKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyB0aWR5IHN0eWxlIGNvZGluZwpsaWJyYXJ5KGJybXMpICMgQmF5ZXNpYW4gbW9kZWxzCmxpYnJhcnkoYmF5ZXNwbG90KSAjIHByZXR0eSBiYXllcyB2aXN1YWxzCmxpYnJhcnkodGlkeWJheWVzKSAjIEJheWVzaWFuIGFlc3RoZXRpY3MKbGlicmFyeShsb28pICMgdG8gdXNlIGluZm9ybWF0aW9uIGNyaXRlcmlhIGluIGJybXMgbW9kZWxzCmxpYnJhcnkoTWV0QnJld2VyKSAjIGNvbG91cnMKbGlicmFyeShyY2FydG9jb2xvcikgIyBtb3JlIGNvbG91cnMKbGlicmFyeShrYWJsZUV4dHJhKSAjIHRhYmxlcwpsaWJyYXJ5KHBhdGNod29yaykgIyBwdXR0aW5nIHBsb3RzIHRvZ2V0aGVyCmxpYnJhcnkoRFQpICMgZm9yIHNlYXJjaC0gYW5kIHNhdmVhYmxlIHRhYmxlcwpsaWJyYXJ5KGdnZGlzdCkgIyBmb3IgcmliYm9uIHBsb3QKYGBgCgojIE1vcnRhbGl0eSBhbmFseXNpcwoKJH4kCgpXZSBjb25kdWN0ZWQgc2luZ2xlLXBhaXIgZnVsbC1zaWJsaW5nIGNyb3NzZXMgdG8gZXJvZGUgaGV0ZXJvenlnb3NpdHkgYWNyb3NzIHRoZSBnZW5vbWUsIHRoZXJlYnkgZXhwb3NpbmcgbXV0YXRpb24gbG9hZC4gT3VyIHByb3hpZXMgZm9yIG11dGF0aW9uIGxvYWQgLSBleHRpbmN0aW9uIHJhdGUgYW5kIHByb2R1Y3Rpdml0eSBkZWNsaW5lIC0gbWF5IGFsc28gaGF2ZSBiZWVuIGFmZmVjdGVkIGJ5IGRpZmZlcmVuY2VzIGluIHRoZSBpbnRlbnNpdHkgb2YgaW50ZXJsb2N1cyBzZXh1YWwgY29uZmxpY3QgYmV0d2VlbiBsaW5lYWdlcyBjYXJyeWluZyBhdXRvc29tZXMgd2l0aCBkaWZmZXJlbnQgc2VsZWN0aW9uIHJlc3BvbnNlIGhpc3Rvcmllcy4gKipXZSBzcGVjaWZpY2FsbHkgZGVzaWduZWQgb3VyIGV4cGVyaW1lbnQgdG8gbWluaW1pc2UgdGhpcyBlZmZlY3QqLCBieSBlbmZvcmNpbmcgbW9ub2dhbXkgYmV0d2VlbiBhbGwgYnJlZWRpbmcgaW5kaXZpZHVhbHMgYWNyb3NzIHRoZSBleHRpbmN0aW9uIGFzc2F5LiBIb3dldmVyLCB3ZSBjYW5ub3QgZGlzY291bnQgbWFsZXMgY2FycnlpbmcgbWFsZS1saW1pdGVkIGF1dG9zb21lcyBhbmQvIG9yIGNvbnRyb2wgYXV0b3NvbWVzIGJlaW5nIG1vcmUgaGFybWZ1bCB0byBmZW1hbGVzIHRoYW4gbWFsZXMgY2FycnlpbmcgYXV0b3NvbWVzIHdpdGggYSBmZW1hbGUtbGltaXRlZCBzZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yeS4gVGhpcyBtaWdodCBvY2N1ciBiZWNhdXNlIG1hbGUgaGFybSBpcyBhIGJ5LXByb2R1Y3Qgb2YgbWFsZS1tYWxlIGNvbXBldGl0aW9uLCB3aGljaCBjYW5ub3QgcmVzcG9uZCB0byBzZWxlY3Rpb24gaW4gdGhlIGZlbWFsZS1saW1pdGVkIHRyZWF0bWVudHMuIEZ1cnRoZXJtb3JlLCB0cmFpdHMgZ2VuZXRpY2FsbHkgY29ycmVsYXRlZCB3aXRoIGhhcm0gc3VjaCBhcyBhY3Rpdml0eSBsZXZlbHMgb3IgbWV0YWJvbGljIHJhdGUgbWF5IGJlIHNlbGVjdGVkIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb24gYW1vbmcgZmVtYWxlcywgYXMgdGhlc2UgdHJhaXRzIGFyZSBoaWdobHkgc2V4dWFsbHkgZGltb3JwaGljLiBUaGlzIG1heSBkcml2ZSB0aGUgZXZvbHV0aW9uIG9mIHJlZHVjZWQgaGFybSBkdXJpbmcgZmVtYWxlLWxpbWl0ZWQgZXZvbHV0aW9uLiAKCldlIG9ic2VydmUgMTM1IGZlbWFsZSAoNi4yJSkgYW5kIDIxICgxJSkgbWFsZSBtb3J0YWxpdGllcyBhY3Jvc3MgdGhlIDIxODQgX0Ryb3NvcGhpbGFfIHZpYWxzIHVzZWQgZHVyaW5nIHRoZSAyMCBnZW5lcmF0aW9ucyBvZiB0aGUgZXhwZXJpbWVudCAod2UgZG8gbm90IGluY2x1ZGUgdGhlIDkgZmluYWwgZ2VuZXJhdGlvbnMgb2JzZXJ2ZWQgaW4gQmxvY2sgMSBpbiB0aGlzIGFuYWx5c2lzKS4gTWFsZSBtb3J0YWxpdHkgZGlkIG5vdCBvY2N1ciBvZnRlbiBlbm91Z2ggdG8gcHJvdmlkZSB0aGUgcG93ZXIgcmVxdWlyZWQgZm9yIGZvcm1hbCBhbmFseXNpcy4gV2UgaW5zdGVhZCBmb2N1cyBvbiBtb2RlbGxpbmcgZmVtYWxlIG1vcnRhbGl0eSBhbmQgdGVzdCB3aGV0aGVyIHRoaXMgaXMgYWZmZWN0ZWQgYnkgc2VsZWN0aW9uIHJlc3BvbnNlIGhpc3RvcnkuIAoKV2UgdGVzdCB0aGlzIGh5cG90aGVzaXMgdG8gYXNzZXNzIHdoZXRoZXIgaXQgaXMgcmVxdWlyZWQgdG8gY2Vuc29yIGxpbmVhZ2VzIHdoZXJlIHRoZSBicmVlZGluZyBmZW1hbGUgZGllZCBpbiB0aGUgZ2VuZXJhdGlvbiBvZiBleHRpbmN0aW9uLgoKJH4kCgojIyBMb2FkIGluIHRoZSBkYXRhCgpgYGB7cn0KCm1vcnRhbGl0eV9kYXRhIDwtIAogIHJlYWRfY3N2KCJEYXRhL01vcnRhbGl0eV9kYXRhLmNzdiIpICU+JSAKICByb3dpZF90b19jb2x1bW4oIkxpbmVhZ2UiKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSA4OjI3LCBuYW1lc190byA9ICJHZW5lcmF0aW9uIiwgdmFsdWVzX3RvID0gIkZlbWFsZV9tb3J0YWxpdHkiKSAlPiUgCiAgbXV0YXRlKGFjcm9zcygxOjcsIGFzLmZhY3RvciksCiAgICAgICAgIEdlbmVyYXRpb24gPSBhcy5pbnRlZ2VyKHN0cl9yZW1vdmUoR2VuZXJhdGlvbiwgIkdlbl8iKSksCiAgICAgICAgIE1hbGVfbW9ydGFsaXR5ID0gRmVtYWxlX21vcnRhbGl0eSwKICAgICAgICAgRmVtYWxlX21vcnRhbGl0eSA9IGlmX2Vsc2UoRmVtYWxlX21vcnRhbGl0eSA9PSAiRkVNQUxFIiB8IEZlbWFsZV9tb3J0YWxpdHkgPT0gIkJPVEgiLCAxLCAwKSwKICAgICAgICAgTWFsZV9tb3J0YWxpdHkgPSBpZl9lbHNlKE1hbGVfbW9ydGFsaXR5ID09ICJNQUxFIiB8IE1hbGVfbW9ydGFsaXR5ID09ICJCT1RIIiwgMSwgMCkpCgpgYGAKCiR+JAoKIyMgTW9kZWxsaW5nIGFwcHJvYWNoCgokfiQKCldlIGZpdCBhIGJpbm9taWFsIG1vZGVsIHdpdGggYEV2b2x1dGlvbl90cmVhdG1lbnRgIGFuZCBgQmxvY2tgIGFzIGZpeGVkIGVmZmVjdHMgYXMgd2VsbCBhcyBgTGluZWFnZWAgYW5kIGBDcm9zc2AgYXMgcmFuZG9tIGVmZmVjdHMuCgpgYGB7cn0KbW9ydGFsaXR5X21vZGVsIDwtIAogIGJybShGZW1hbGVfbW9ydGFsaXR5IH4gMSArIFRyZWF0bWVudCArIEJsb2NrICsgKDF8Q3Jvc3MpICsgKDF8TGluZWFnZSksCiAgICAgIGRhdGEgPSBtb3J0YWxpdHlfZGF0YSAlPiUgZmlsdGVyKEZlbWFsZV9tb3J0YWxpdHkgIT0gIk5BIiksCiAgICAgIGZhbWlseSA9IGJlcm5vdWxsaSwKICAgICAgcHJpb3IgPSBjKHByaW9yKG5vcm1hbCgwLCAyKSwgY2xhc3MgPSBJbnRlcmNlcHQpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9IGIpLAogICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gc2QpKSwKICAgICAgaXRlciA9IDQwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwgc2VlZCA9IDEsCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NSksCiAgICAgIGZpbGUgPSAiRml0cy9tb3J0YWxpdHlfbW9kZWwiKQpgYGAKCgojIyBFeHRyYWN0IG1vZGVsIHByZWRpY3Rpb25zIGFuZCBwbG90CgpgYGB7cn0KCiMgdGhlc2UgYXJlIHNwZWNpZmljIHRvIGJsb2NrIDEsIGJ1dCB0aGlzIGRvZXNuJ3QgcmVhbGx5IG1hdHRlciBiZWNhdXNlIHRoZXJlIGlzIG5vIGludGVyYWN0aW9uIGJldHdlZW4gdHJlYXRtZW50IGFuZCBibG9jay4KCm1vcnRhbGl0eV9wcmVkaWN0aW9ucyA8LQogIG1vcnRhbGl0eV9tb2RlbCAlPiUgCiAgYXNfZHJhd3NfZGYoKSAlPiUgCiAgbXV0YXRlKENvbnRyb2wgPSBpbnZfbG9naXRfc2NhbGVkKGJfSW50ZXJjZXB0KSwKICAgICAgICAgYEZlbWFsZS1saW1pdGVkYCA9IGludl9sb2dpdF9zY2FsZWQoYl9JbnRlcmNlcHQgKyBiX1RyZWF0bWVudEZlbWFsZSksCiAgICAgICAgIGBNYWxlLWxpbWl0ZWRgID0gaW52X2xvZ2l0X3NjYWxlZChiX0ludGVyY2VwdCArIGJfVHJlYXRtZW50TWFsZSkpICU+JSAKICBzZWxlY3QoQ29udHJvbCwgYEZlbWFsZS1saW1pdGVkYCwgYE1hbGUtbGltaXRlZGApCgojIHB1dCBpbiBlYXN5IHRvIHBsb3QgZm9ybWF0Cgptb3J0YWxpdHlfcHJlZGljdGlvbnNfbG9uZyA8LQogIG1vcnRhbGl0eV9wcmVkaWN0aW9ucyAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gIkV2b2x1dGlvbl90cmVhdG1lbnQiLCB2YWx1ZXNfdG8gPSAiTW9ydGFsaXR5IikKCiMgY2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGVhY2ggdHJlYXRtZW50Cgptb3J0YWxpdHlfZGlmZiA8LQogIG1vcnRhbGl0eV9wcmVkaWN0aW9ucyAlPiUgCiAgbXV0YXRlKGBDb250cm9sIC0gTWFsZS1saW1pdGVkYCA9IENvbnRyb2wgLSBgTWFsZS1saW1pdGVkYCwKICAgICAgICAgYE1hbGUtbGltaXRlZCAtIEZlbWFsZS1saW1pdGVkYCA9IGBNYWxlLWxpbWl0ZWRgIC0gYEZlbWFsZS1saW1pdGVkYCwKICAgICAgICAgYENvbnRyb2wgLSBGZW1hbGUtbGltaXRlZGAgPSBDb250cm9sIC0gYEZlbWFsZS1saW1pdGVkYCkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gNDo2LCBuYW1lc190byA9ICJEaWZmZXJlbmNlX2NvbnRyYXN0IiwgdmFsdWVzX3RvID0gIkRpZmZlcmVuY2UiKSAlPiUgCiAgc2VsZWN0KGNvbnRhaW5zKCJEaWZmIikpCgpgYGAKCiMjIEJ1aWxkIEZpZ3VyZSBTWAoKYGBge3J9Cm1vcnRhbGl0eV9wbG90IDwtCiAgbW9ydGFsaXR5X3ByZWRpY3Rpb25zX2xvbmcgJT4lIAogIGdncGxvdChhZXMoeCA9IE1vcnRhbGl0eSwgeSA9IEV2b2x1dGlvbl90cmVhdG1lbnQpKSArCiAgICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBFdm9sdXRpb25fdHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxLAogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsIAogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LAogICAgICAgICAgICAgICBzbGFiX2NvbG91ciA9ICJibGFjayIsIHNsYWJfc2l6ZSA9IDAuOCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDUpKSArCiAgbGFicyh4PSAiRmVtYWxlIG1vcnRhbGl0eSAocHJvcC4pIiwgeSA9ICJTZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yeSIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcpLCAjdHJhbnNwYXJlbnQgcGFuZWwgYmcKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvcj1OQSksICN0cmFuc3BhcmVudCBwbG90IGJnCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCgptb3J0YWxpdHlfZGlmZl9wbG90IDwtIAogIG1vcnRhbGl0eV9kaWZmICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBEaWZmZXJlbmNlLCB5ID0gZmN0X3JlbGV2ZWwoRGlmZmVyZW5jZV9jb250cmFzdCwgIkZlbWFsZSAtIENvbnRyb2wiLCAiTWFsZSAtIEZlbWFsZSIsICJNYWxlIC0gQ29udHJvbCIpKSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IERpZmZlcmVuY2VfY29udHJhc3QpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwKICAgICAgICAgICAgICAgc2xhYl9jb2xvdXIgPSAiYmxhY2siLCBzbGFiX3NpemUgPSAwLjgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhjYXJ0b19wYWwoNywgIlBlYWNoIilbMl0sIGNhcnRvX3BhbCg3LCAiUHVycCIpWzFdLCBjYXJ0b19wYWwoNywgIlRlYWxHcm4iKVsxXSkpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIkRpZmYuIGluIG1vcnRhbGl0eSIsIHkgPSAiVHJlYXRtZW50IGNvbnRyYXN0IikgKwogICNzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtNCwgNiwgMikpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcpLCAjdHJhbnNwYXJlbnQgcGFuZWwgYmcKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCgptb3J0YWxpdHlfcGxvdCAvIG1vcnRhbGl0eV9kaWZmX3Bsb3QKYGBgCgoqKkZpZ3VyZSBTWCoqLgoKJH4kCgpGZW1hbGUgbW9ydGFsaXR5IGlzIGxlc3MgZnJlcXVlbnQgaW4gbGluZWFnZXMgd2l0aCBmZW1hbGUtbGltaXRlZCBzZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yaWVzLCBzdWdnZXN0aW5nIHRoYXQgbWFsZSBoYXJtICoqbWF5KiogYmUgbGVzcyBpbnRlbnNlIGluIHRoZXNlIGxpbmVhZ2VzLiBUbyBhdm9pZCB0aGlzIGNvbmZvdW5kaW5nIG91ciBtZWFzdXJlIG9mIG11dGF0aW9uIGxvYWQsIHdlIGNhbiBjZW5zb3IgZXh0aW5jdGlvbiBldmVudHMgdGhhdCBjby1vY2N1ciB3aXRoIGZlbWFsZSBtb3J0YWxpdHkuCgokfiQKCiMgRXh0aW5jdGlvbiBhbmFseXNpcwoKIyMgTG9hZCBpbiB0aGUgZXh0aW5jdGlvbiBkYXRhIAoKJH4kCgpgYGB7cn0KCmV4dGluY3Rpb25fZGF0YSA8LSAKICByZWFkX2NzdigiRGF0YS9FeHRpbmN0aW9uX2RhdGEuY3N2IikgCgojIEJsb2NrIDEgcnVucyBmb3IgMjkgZ2VuZXJhdGlvbnMsIHdoaWxlIEJsb2NrIDIgb25seSBydW5zIGZvciAyMC4gVG8gY2FsY3VsYXRlIHRoZSBjZW5zb3JpbmcgdmFyaWFibGUsIHdlIG5lZWQgdG8gc3BsaXQgdGhlc2UgYnkgQmxvY2ssIG11dGF0ZSB0aGUgZGF0YSwgdGhlbiByZWJpbmQgdGhlbSAKCkJsb2NrXzEgPC0KICBleHRpbmN0aW9uX2RhdGEgJT4lIAogIGZpbHRlcihCbG9jayA9PSAiMSIpICU+JSAKICAjIGhlcmUgd2UgY3JlYXRlIGEgY2Vuc29yaW5nIGNvbHVtbi4gSWYgdGhlIGZhbWlseSBhKSBlc2NhcGVkIG9yIHdhcyBraWxsZWQgYnkgc29tZXRoaW5nIHVucmVsYXRlZCB0byB0aGUgZXhwZXJpbWVudCBvciBiKSBzdXJ2aXZlZCB0aGUgMjAgZ2VuZXJhdGlvbnMgb2YgdGhlIGV4cGVyaW1lbnQsIHRoZW4gd2UgY29kZSBhIHZhbHVlIG9mIDEuIElmIHRoZSBmYW1pbHkgd2VudCBleHRpbmN0LCB3ZSBjb2RlIGEgdmFsdWUgb2YgMC4gVGhpcyBhbGxvd3MgdXMgdG8gcmlnaHQgY2Vuc29yIHRoZSBkYXRhLCB0aGVyZWJ5IHByZXNlcnZpbmcgdGhlIGluZm9ybWF0aW9uIGl0IHByb3ZpZGVzIG9uIGV4dGluY3Rpb24uCiAgbXV0YXRlKGFjcm9zcyhHZW5fMTpHZW5fMjksIH5yZXBsYWNlX25hKC54LCAiRXNjYXBlIikpLAogICAgICAgICBDZW5zb3JlZF9hbGl2ZSA9IGlmX2Vsc2UoR2VuXzI5ID09ICJZRVMiLCAxLCAwKSwKICAgICAgICAgQ2Vuc29yZWRfZXNjYXBlID0gaWZfZWxzZShHZW5fMjkgPT0gIkVzY2FwZSIsIDEsIDApLAogICAgICAgICBDZW5zb3JlZCA9IENlbnNvcmVkX2FsaXZlICsgQ2Vuc29yZWRfZXNjYXBlLAogICAgICAgICBhY3Jvc3MoR2VuXzE6R2VuXzI5LCB+aWZfZWxzZSgueCA9PSAiWUVTIiwgMSwgMCkpKQogICAgICAgIAoKQmxvY2tfMiA8LQogIGV4dGluY3Rpb25fZGF0YSAlPiUgCiAgZmlsdGVyKEJsb2NrID09ICIyIikgJT4lIAogICMgaGVyZSB3ZSBjcmVhdGUgYSBjZW5zb3JpbmcgY29sdW1uLiBJZiB0aGUgZmFtaWx5IGEpIGVzY2FwZWQgb3Igd2FzIGtpbGxlZCBieSBzb21ldGhpbmcgdW5yZWxhdGVkIHRvIHRoZSBleHBlcmltZW50IG9yIGIpIHN1cnZpdmVkIHRoZSAyMCBnZW5lcmF0aW9ucyBvZiB0aGUgZXhwZXJpbWVudCwgdGhlbiB3ZSBjb2RlIGEgdmFsdWUgb2YgMS4gSWYgdGhlIGZhbWlseSB3ZW50IGV4dGluY3QsIHdlIGNvZGUgYSB2YWx1ZSBvZiAwLiBUaGlzIGFsbG93cyB1cyB0byByaWdodCBjZW5zb3IgdGhlIGRhdGEsIHRoZXJlYnkgcHJlc2VydmluZyB0aGUgaW5mb3JtYXRpb24gaXQgcHJvdmlkZXMgb24gZXh0aW5jdGlvbi4KICBtdXRhdGUoYWNyb3NzKEdlbl8xOkdlbl8yMCwgfnJlcGxhY2VfbmEoLngsICJFc2NhcGUiKSksCiAgICAgICAgIGFjcm9zcyhHZW5fMjE6R2VuXzI5LCB+cmVwbGFjZV9uYSgueCwgIk5vdCBtZWFzdXJlZCIpKSwKICAgICAgICAgQ2Vuc29yZWRfYWxpdmUgPSBpZl9lbHNlKEdlbl8yMCA9PSAiWUVTIiwgMSwgMCksCiAgICAgICAgIENlbnNvcmVkX2VzY2FwZSA9IGlmX2Vsc2UoR2VuXzIwID09ICJFc2NhcGUiLCAxLCAwKSwKICAgICAgICAgQ2Vuc29yZWQgPSBDZW5zb3JlZF9hbGl2ZSArIENlbnNvcmVkX2VzY2FwZSwKICAgICAgICAgYWNyb3NzKEdlbl8xOkdlbl8yOSwgfmlmX2Vsc2UoLnggPT0gIllFUyIsIDEsIDApKSkKCiMgY29tYmluZSB0aGUgQmxvY2tlZCBkYXRhIGJhY2sgaW50byBhIHNpbmdsZSB0aWJibGUKCmV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCA8LQogIHJiaW5kKEJsb2NrXzEsIEJsb2NrXzIpICU+JQogIG11dGF0ZShhY3Jvc3MoMTo3LCBhcy5mYWN0b3IpLCAKICAgICAgICAgR2Vuc190b19leHRpbmN0ID0gR2VuXzEgKyBHZW5fMiArIEdlbl8zICsgR2VuXzQgKyAKICAgICAgICAgICBHZW5fNSArIEdlbl82ICsgR2VuXzcgKyBHZW5fOCArIEdlbl85ICsgR2VuXzEwICsgCiAgICAgICAgICAgR2VuXzExICsgR2VuXzEyICsgR2VuXzEzICsgR2VuXzE0ICsgR2VuXzE1ICsgR2VuXzE2ICsgCiAgICAgICAgICAgR2VuXzE3ICsgR2VuXzE4ICsgR2VuXzE5ICsgR2VuXzIwICsgR2VuXzIxICsgR2VuXzIyICsgCiAgICAgICAgICAgR2VuXzIzICsgR2VuXzI0ICsgR2VuXzI1ICsgR2VuXzI2ICsgR2VuXzI3ICsgR2VuXzI4ICsgR2VuXzI5ICsgMSkgJT4lIAogIHJlbmFtZShFdm9sdXRpb25fdHJlYXRtZW50ID0gVHJlYXRtZW50LCBMaW5lYWdlICA9IElEKSAlPiUgCiAgc2VsZWN0KE1vdGhlcl9zdHJhaW4sIEZhdGhlcl9zdHJhaW4sIENyb3NzLCBMaW5lYWdlLCBCbG9jaywgCiAgICAgICAgIEV2b2x1dGlvbl90cmVhdG1lbnQsIEdlbnNfdG9fZXh0aW5jdCwgR2VuXzE6R2VuXzI5LCBDZW5zb3JlZF9hbGl2ZSwgCiAgICAgICAgIENlbnNvcmVkX2VzY2FwZSwgQ2Vuc29yZWQpCgojIEZpbmQgdGhlIGV4dGluY3Rpb25zIHRoYXQgY28tb2NjdXIgd2l0aCBmZW1hbGUgbW9ydGFsaXR5CgpleHRpbmN0aW9uX21vcnRhbGl0eSA8LQogIGxlZnRfam9pbigKICAgIGV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCAlPiUgCiAgICAgIHBpdm90X2xvbmdlcihjb2xzID0gODozNiwgbmFtZXNfdG8gPSAiR2VuZXJhdGlvbiIsIHZhbHVlc190byA9ICJFeHRhbnQiKSAlPiUgCiAgICAgIG11dGF0ZShHZW5lcmF0aW9uID0gYXMuaW50ZWdlcihzdHJfcmVtb3ZlKEdlbmVyYXRpb24sICJHZW5fIikpKSwKICAgIAogICAgbW9ydGFsaXR5X2RhdGEKICApICU+JSAKICBmaWx0ZXIoRXh0YW50ID09IDAgJiBGZW1hbGVfbW9ydGFsaXR5ID09IDEpICU+JSAKICBtdXRhdGUoQ2Vuc29yZWRfbW9ydGFsaXR5ID0gMSkgJT4lIAogIHNlbGVjdChMaW5lYWdlLCBDZW5zb3JlZF9tb3J0YWxpdHkpCgpleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQgPC0gbGVmdF9qb2luKGV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCwgZXh0aW5jdGlvbl9tb3J0YWxpdHkpICU+JSAKICBtdXRhdGUoQ2Vuc29yZWRfbW9ydGFsaXR5ID0gaWZfZWxzZShpcy5uYShDZW5zb3JlZF9tb3J0YWxpdHkpLCAwLCAxKSwKICAgICAgICAgQ2Vuc29yZWQgPSBDZW5zb3JlZCArIENlbnNvcmVkX21vcnRhbGl0eSkKCiMgQ3JlYXRlIGEgZnVuY3Rpb24gdG8gYnVpbGQgSFRNTCBzZWFyY2hhYmxlIHRhYmxlcwoKbXlfZGF0YV90YWJsZSA8LSBmdW5jdGlvbihkZil7CiAgZGF0YXRhYmxlKAogICAgZGYsIHJvd25hbWVzPUZBTFNFLAogICAgYXV0b0hpZGVOYXZpZ2F0aW9uID0gVFJVRSwKICAgIGV4dGVuc2lvbnMgPSBjKCJTY3JvbGxlciIsICAiQnV0dG9ucyIpLAogICAgb3B0aW9ucyA9IGxpc3QoCiAgICAgIGRvbSA9ICdCZnJ0aXAnLAogICAgICBkZWZlclJlbmRlcj1UUlVFLAogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLAogICAgICBzY3JvbGxDb2xsYXBzZT1UUlVFLAogICAgICBidXR0b25zID0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KAogICAgICAgICAgZXh0ZW5kID0gJ3BkZicsCiAgICAgICAgICBwYWdlU2l6ZSA9ICdBNCcsCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLAogICAgICAgICAgZmlsZW5hbWUgPSAnZXh0aW5jdGlvbl9kYXRhJykpLAogICAgICBwYWdlTGVuZ3RoID0gNTAwCiAgICApCiAgKQp9CgpteV9kYXRhX3RhYmxlKGV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCkKYGBgCgoqKkNvbHVtbiBleHBsYW5hdGlvbnMqKgoKYE1vdGhlciBzdHJhaW5gOiB3ZSBtZWFzdXJlZCBleHRpbmN0aW9uIGFuZCBwcm9kdWN0aXZpdHkgb2YgZmFtaWxpZXMgZGVyaXZlZCBmcm9tIDM2IGRpZmZlcmVudCBjcm9zc2VzLiBDcm9zc2VzIHdlcmUgb25seSBjb25kdWN0ZWQgYmV0d2VlbiBzdHJhaW5zIHRoYXQgZXhwZXJpZW5jZWQgdGhlIHNhbWUgYEV2b2x1dGlvbl90cmVhdG1lbnRgLiBUaGlzIGNvbHVtbiBzaG93cyB0aGUgc3RyYWluIHRoYXQgdGhlIGZvdW5kaW5nIGZlbWFsZSBvZiB0aGUgbGluZWFnZSB3YXMgZGVyaXZlZCBmcm9tLgoKYEZhdGhlciBzdHJhaW5gOiB3ZSBtZWFzdXJlZCBleHRpbmN0aW9uIGFuZCBwcm9kdWN0aXZpdHkgb2YgZmFtaWxpZXMgZGVyaXZlZCBmcm9tIDM2IGRpZmZlcmVudCBjcm9zc2VzLiBDcm9zc2VzIHdlcmUgb25seSBjb25kdWN0ZWQgYmV0d2VlbiBzdHJhaW5zIHRoYXQgZXhwZXJpZW5jZWQgdGhlIHNhbWUgZXZvbHV0aW9uIHRyZWF0bWVudC4gVGhpcyBjb2x1bW4gc2hvd3MgdGhlIHN0cmFpbiB0aGF0IHRoZSBmb3VuZGluZyBtYWxlIG9mIHRoZSBsaW5lYWdlIHdhcyBkZXJpdmVkIGZyb20uCgpgQ3Jvc3NgOiBhbiBpZGVudGlmeWluZyBJRCBmb3IgZWFjaCBvZiB0aGUgMzYgY29tYmluYXRpb25zIG9mIGBNb3RoZXIgc3RyYWluYCBhbmQgYEZhdGhlciBzdHJhaW5gLiAKCmBMaW5lYWdlYDogbGluZXMgb2YgZmxpZXMgZm91bmRlZCBieSBzaW5nbGUgaW5zZW1pbmF0ZWQgZmVtYWxlcyBpbiBnZW5lcmF0aW9uIHplcm8uIFdlIGdlbmVyYXRlZCB0aGUgbmV4dCBnZW5lcmF0aW9uIG9mIGVhY2ggbGluZWFnZSBieSBjcm9zc2luZyBhIHNpbmdsZSBmdWxsLXNpYmxpbmcgZHlhZC4KCmBCbG9ja2A6IHRoZSBleHBlcmltZW50IHdhcyBydW4gaW4gMiBkaXN0aW5jdCBibG9ja3MsIHVzaW5nIGZsaWVzIHNlcGFyYXRlZCBieSA5IGdlbmVyYXRpb25zLgoKYEV2b2x1dGlvbl90cmVhdG1lbnRgOiB0aGUgc3RyYWlucyBoYWQgYmVlbiBleHBvc2VkIHRvIG9uZSBvZiB0aHJlZSBldm9sdXRpb25hcnkgY29uZGl0aW9ucyBmb3IgMjAgZ2VuZXJhdGlvbnM6IGEgZmVtYWxlLWxpbWl0ZWQgcmVzcG9uc2UgdG8gc2VsZWN0aW9uLCBhIG1hbGUtbGltaXRlZCByZXNwb25zZSBhbmQgYSBjb250cm9sIGNvbmRpdGlvbiB3aGVyZSBhbiBldm9sdXRpb25hcnkgcmVzcG9uc2Ugb2NjdXJyZWQgaW4gYm90aCBzZXhlcy4KCmBHZW5zX3RvX2V4dGluY3Rpb25gOiB0aGUgbnVtYmVyIG9mIGdlbmVyYXRpb25zIHRoZSBsaW5lYWdlIHN1cnZpdmVkIHVudGlsIGl0IHdlbnQgZXh0aW5jdC4KCmBHZW5fMToyOWA6IGEgMSBpbmRpY2F0ZXMgdGhlIGxpbmVhZ2Ugd2FzIGV4dGFudCBmb3IgdGhlIGdlbmVyYXRpb24gaW4gcXVlc3Rpb24sIHdoaWxlIGEgMCBpbmRpY2F0ZXMgZXh0aW5jdGlvbi4gTm90ZSB0aGF0IHdlIGNvbnRpbnVlZCBwcm9wYWdhdGluZyBzdXJ2aXZpbmcgbGluZWFnZXMgZnJvbSBCbG9jayAxIHVudGlsIGdlbmVyYXRpb24gMjksIHdoaWNoIGNvaW5jaWRlZCB3aXRoIGdlbmVyYXRpb24gMjAgZm9yIGxpbmVhZ2VzIGJlbG9uZ2luZyB0byB0aGUgc2Vjb25kIEJsb2NrLgoKYENlbnNvcmVkYDogaWYgdGhlIGxpbmVhZ2UgMSkgZW5kZWQgYmVjYXVzZSBmbGllcyBlc2NhcGVkIG9yIHdlcmUga2lsbGVkIGJ5IHNvbWV0aGluZyB1bnJlbGF0ZWQgdG8gdGhlIGV4cGVyaW1lbnQsIDIpIHdlbnQgZXh0aW5jdCBiZWNhdXNlIG9mIGJyZWVkaW5nIGZlbWFsZSBtb3J0YWxpdHkgb3IgMykgd2FzIGV4dGFudCBpbiB0ZWggZmluYWwgZ2VuZXJhdGlvbiBvZiB0aGUgZXhwZXJpbWVudCwgdGhlbiB3ZSBjb2RlZCBhIHZhbHVlIG9mIDEuIElmIHRoZSBsaW5lYWdlIHdlbnQgZXh0aW5jdCwgd2UgY29kZWQgYSB2YWx1ZSBvZiAwLiBUaGlzIGFsbG93cyB1cyB0byByaWdodCBjZW5zb3IgdGhlIGRhdGEgYXMgcGVyIHRoZSBgYnJtc2Agc3ludGF4LCB0aGVyZWJ5IHByZXNlcnZpbmcgdGhlIGluZm9ybWF0aW9uIHRoZXNlIGNlbnNvcmVkIGNhc2VzIHByb3ZpZGUgb24gZXh0aW5jdGlvbi4KCiR+JAoKIyMgTW9kZWxsaW5nIGFwcHJvYWNoCgokfiQKCldlIGZpdCBhIHdlaWJ1bGwgc3Vydml2YWwgbW9kZWwgdG8gZXN0aW1hdGUgXGxhbWJkYSwgdGhlIGV4dGluY3Rpb24gcmF0ZSBvZiB0aGUgbGluZWFnZXMgdXNlZCBpbiBvdXIgZXhwZXJpbWVudC4gVGhlIHdlaWJ1bGwgbW9kZWwgaXMgYW4gZXh0ZW5zaW9uIG9mIGFuIGV4cG9uZW50aWFsIGRlY2F5IG1vZGVsLCBhbmQgaW5jbHVkZXMgYW4gYWRkaXRpb25hbCBzaGFwZSBwYXJhbWV0ZXIsIHdoaWNoIGFsbG93cyBcbGFtYmRhIHRvIHZhcnkgYWNyb3NzIGdlbmVyYXRpb25zIG9mIGluYnJlZWRpbmcuIAoKKipSZXNwb25zZSB2YXJpYWJsZSoqCgpgR2Vuc190b19leHRpbmN0YCBpcyBvdXIgcmVzcG9uc2UgLSBhIGNvbnRpbnVvdXMgdmFyaWFibGUgdGhhdCBydW5zIGZyb20gMSB0byAzMCBnZW5lcmF0aW9ucy4gTm90ZSB0aGF0IHdlIG1lYXN1cmVkIGV4dGluY3Rpb24gdXAgdW50aWwgZ2VuZXJhdGlvbiAyOSBpbiBCbG9jayAxIGFuZCBnZW5lcmF0aW9uIDIwIGluIEJsb2NrIDIuIEEgdmFsdWUgb2YgMzAgaW5kaWNhdGVzIHRoYXQgdGhlIGxpbmVhZ2Ugd2FzIGV4dGFudCBhdCB0aGUgZW5kIG9mIHRoZSBleHBlcmltZW50IGluIEJsb2NrIDEsIHdoaWxlIGEgdmFsdWUgb2YgMjEgaW5kaWNhdGVzIHRoaXMgaW4gQmxvY2sgMi4gV2UgYWxzbyBpbmNsdWRlIHJpZ2h0IGNlbnNvcmluZywgdG8gYWNjb3VudCBmb3IgbGluZWFnZXMgZXh0YW50IGF0IHRoZSBlbmQgb2YgdGhlIGV4cGVyaW1lbnQsIG9yIHRoYXQgd2VyZSByZW1vdmVkIGZyb20gdGhlIGV4cGVyaW1lbnQgYnkgYSBoYW5kbGluZyBlcnJvci4gQ2Vuc29yaW5nIGVuYWJsZXMgdGhlIGluY2x1c2lvbiBvZiB0aGlzICdpbmNvbXBsZXRlJyBkYXRhIGluIHRoZSBtb2RlbC4gCgoqKkZpeGVkIGVmZmVjdHMqKgoKYEV2b2x1dGlvbl90cmVhdG1lbnRgOiB3ZSBpbmNsdWRlIHRoaXMgdG8gdGVzdCBmb3IgYSBjYXVzYWwgZWZmZWN0IG9mIHNleC1saW1pdGVkIGV4cGVyaW1lbnRhbCBldm9sdXRpb24gb24gbXV0YXRpb24gbG9hZC4gCgpgQmxvY2tgOiBleHRpbmN0aW9uIHJhdGUgbWlnaHQgZGlmZmVyIGJldHdlZW4gdGhlIGJsb2NrcyB3ZSBzcGxpdCBvdXIgZXhwZXJpbWVudCB1cCBpbnRvIGUuZy4gYmVjYXVzZSBvZiBtaWNyb3ZhcmlhdGlvbiBpbiB0aGUgbGFiIGJyb3VnaHQgYWJvdXQgYmVjYXVzZSBvZiBhIGNoYW5nZSBvZiBzZWFzb24sIHNsaWdodCBpbmNvbnNpc3RlbmNpZXMgaW4gX0Ryb3NvcGhpbGFfIGZvb2QgY29uc2lzdGVuY3kgZXRjLgoKKipWYXJ5aW5nL1JhbmRvbSBlZmZlY3RzKioKCmBDcm9zc2A6IHdlIGluaXRpYXRlZCBlYWNoIGxpbmVhZ2UgYnkgY3Jvc3NpbmcgdHdvIHN0cmFpbnMgYmVsb25naW5nIHRvIHRoZSBzYW1lIGV2b2x1dGlvbiB0cmVhdG1lbnQuIFRoZXJlIHdlcmUgMTIgbGV2ZWxzIG9mIGNyb3NzIG5lc3RlZCB3aXRoaW4gZXZvbHV0aW9uIHRyZWF0bWVudCwgZm9yIGEgdG90YWwgb2YgMzYgY3Jvc3Nlcy4gV2Uga2VwdCBsaW5lYWdlcyBmcm9tIHRoZSBzYW1lIGBDcm9zc2AgYW5kIGBCbG9ja2AgaW4gdGhlIHNhbWUgY29sdW1uIG9mIHRoZSBfRHJvc29waGlsYV8gdmlhbCB0cmF5cywgc28gaW5jdWRpbmcgdGhpcyB2YXJpYWJsZSBhbHNvIGNvbnRyb2xzIGZvciBtaWNyby1lbnZpcm9ubWVudGFsIHZhcmlhdGlvbiBjYXVzZWQgYnkgd2l0aGluLXRyYXkgcG9zaXRpb24uIFdlIHVzZWQgdGhpcyByYW5kb20gZWZmZWN0IGluIG91ciBmaXJzdCBtb2RlbC4KCmBNb3RoZXJfc3RyYWluYCBhbmQgYEZhdGhlcl9zdHJhaW5gOiBVc2VkIGFzIGFuIGFsdGVybmF0aXZlIHRvIGBDcm9zc2AgaW4gb3VyIHNlY29uZCBtb2RlbC4gSW4gdGhpcyBjYXNlLCB3ZSBmaXQgYSBtdWx0aS1tZW1iZXJzaGlwIG1vZGVsLCB3aGVyZSBlYWNoIGxpbmVhZ2Ugc2ltdWx0YW5lb3VzbHkgYmVsb25ncyB0byB0d28gbGV2ZWxzIG9mIHRoZSBgQ3Jvc3NgIHJhbmRvbSBlZmZlY3QuIFRoYXQgaXMsIGVhY2ggbGluZWFnZSB3YXMgZm91bmRlZCBteSBhIG1vdGhlciBmcm9tICRzdHJhaW5faSQgYW5kIGEgZmF0aGVyIGZyb20gJHN0cmFpbl9qJCBhbmQgdGhleSB0aGVyZWZvcmUgYWx3YXlzIGJlbG9uZyB0byB0d28gbGV2ZWxzIG9mIHN0cmFpbi4gCgoqKk11bHRpLW1lbWJlcnNoaXAgdnMgc2luZ2xlLW1lbWJlcnNoaXAqKgoKV2hpbGUgdGhlIG11bHRpLW1lbWJlcnNoaXAgYXBwcm9hY2ggbWF5IGluaXRpYWxseSBzZWVtIHRoZSBtb3JlIHBvd2VyZnVsIG9mIHRoZSB0d28gcmFuZG9tIGVmZmVjdCBzdHJ1Y3R1cmVzLCB3ZSBmYXZvdXIgdGhlIHNpbmdsZS1tZW1iZXJzaGlwIGFwcHJvYWNoIGZvciBzZXZlcmFsIHJlYXNvbnMuIEZpcnN0LCBvdXIgcHJpbWFyeSBhaW0gaXMgdG8gZXN0aW1hdGUgdGhlIG92ZXJhbGwgY2F1c2FsIGVmZmVjdCBvZiBldm9sdXRpb24gdHJlYXRtZW50IG9uIGdlbmVyYXRpb25zIHRvIGV4dGluY3Rpb24sIHJhdGhlciB0aGFuIHRoYXQgb2YgZWFjaCBzdHJhaW4gKG5lc3RlZCB3aXRoaW4gZXZvbHV0aW9uIHRyZWF0bWVudCkuIEdpdmVuIHRoYXQgd2UgYmFsYW5jZWQgb3VyIGNyb3NzaW5nIGRlc2lnbiBzbyB0aGF0IGVhY2ggc3RyYWluIGlzIGVxdWFsbHkgcmVwcmVzZW50ZWQgaW4gdGhlIGV4cGVyaW1lbnQsIGVzdGltYXRpb24gZm9yIGVhY2ggc3RyYWluIGlzIG5vdCBpbnRlZ3JhbC4gU2Vjb25kLCBDcm9zcyBjYXB0dXJlcyBudWlzYW5jZSBlbnZpcm9ubWVudGFsIHZhcmlhdGlvbiB0aGF0IFN0cmFpbiBkb2VzIG5vdC4gV2UgZGlzdHJpYnV0ZWQgbGluZWFnZXMgdGhyb3VnaG91dCB0aHJlZSBfRHJvc29waGlsYV8gdmlhbCB0cmF5cyBieSBwbGFjaW5nIGxpbmVhZ2VzIGZyb20gdGhlIHNhbWUgY3Jvc3MgaW4gdGhlIHNhbWUgY29sdW1uLiBBY3Jvc3MgdGhlIGNvbHVtbnMgd2Ugc3BsaXQgbGluZWFnZXMgdXAgYnkgZXZvbHV0aW9uIHRyZWF0bWVudCwgc3VjaCB0aGF0IGNvbHVtbiBvbmUgY29udGFpbmVkIGxpbmVhZ2VzIGZyb20gdGhlIGZlbWFsZS1saW1pdGVkIHRyZWF0bWVudCwgY29sdW1uIHR3byBjb250YWluZWQgbGluZWFnZXMgZnJvbSB0aGUgbWFsZS1saW1pdGVkIHRyZWF0bWVudCBhbmQgY29sdW1uIHRocmVlIGNvbnRhaW5lZCBsaW5lYWdlcyBmcm9tIHRoZSBjb250cm9sIHRyZWF0bWVudC4gV2UgcmVwZWF0ZWQgdGhpcyBwYXR0ZXJuIHVudGlsIGFsbCAzNiBjcm9zc2VzIGZpbGxlZCBhIGNvbHVtbi4gQXMgYSBzdHJhaW4gaXMgdXNlZCBpbiBtdWx0aXBsZSBjcm9zc2VzLCBpdCBpcyB3aWRlbHkgZGlzdGlyYnV0ZWQgdGhyb3VnaG91dCB0aGUgdHJheXMgYW5kIHRoZXJlZm9yZSBkb2VzIG5vdCBjYXB0dXJlIGEgbG9jYXRpb24gZWZmZWN0IGxpa2UgY3Jvc3MgZG9lcy4gV2UgYXJlIG9mIHRoZSBvcGluaW9uIHRoYXQgY29udHJvbGxpbmcgZm9yIHRoaXMgZW52aXJvbm1lbnRhbCB2YXJpYXRpb24gaXMgb2YgZ3JlYXRlciBpbXBvcnRhbmNlIHRoYW4gc3RyYWluIGxldmVsIGRpZmZlcmVuY2VzIGluIG11dGF0aW9uIGxvYWQsIHdoaWNoIGJvdGggY3Jvc3MgYW5kIGV2b2x1dGlvbiB0cmVhdG1lbnQgYWxzbyBjb250YWluIGluZm9ybWF0aW9uIGZvci4KCkZpbmFsbHksIHdlIGZpdCBib3RoIG1vZGVscyBhbmQgdXNlIGxlYXZlIG9uZSBvdXQgKExPTykgY3Jvc3MgdmFsaWRhdGlvbiB0byBmb3JtYWxseSBhc3Nlc3Mgd2hpY2ggbW9kZWwgaGFzIGJldHRlciBleHBlY3RlZCBwcmVkaWN0aXZlIGFjY3VyYWN5LCBib3RoIGluIGFuZCBvdXQgb2Ygc2FtcGxlLgoKKipQcmlvcnMqKgoKV2UgZml0IG1vZGVyYXRlbHkgaW5mb3JtYXRpdmUgcHJpb3JzLCB3aXRoIHRoZSBhaW0gdG8gcmVndWxhcmlzZSBvdXIgcG9zdGVyaW9yIGVzdGltYXRlcyBhbmQgaW1wcm92ZSBtb2RlbCBmaXR0aW5nIGJ5IHJ1bGluZyBvdXQgbm9uLXNlbnNpY2FsIHZhbHVlcy4KCiMjIEZpdCB0aGUgbW9kZWxzCgpgYGB7cn0KCmV4dGluY3Rpb25fbW9kZWxfc20gPC0KICBicm0oZGF0YSA9IGV4dGluY3Rpb25fZGF0YV93cmFuZ2xlZCwKICAgICAgZmFtaWx5ID0gd2VpYnVsbCwKICAgICAgYmYoR2Vuc190b19leHRpbmN0IHwgY2VucyhDZW5zb3JlZCkgfiAxICsgRXZvbHV0aW9uX3RyZWF0bWVudCArIEJsb2NrICsgKDF8Q3Jvc3MpLAogICAgICAgICBzaGFwZSB+IDEgKyBFdm9sdXRpb25fdHJlYXRtZW50ICsgQmxvY2spLAogICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9IEludGVyY2VwdCksIAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9IGIpLAogICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gc2QpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAsIDEpLCBjbGFzcyA9IGIsIGRwYXIgPSBzaGFwZSkpLCAKICAgICAgaXRlciA9IDgwMDAsIHdhcm11cCA9IDQwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwKICAgICAgc2VlZCA9IDEsIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gLjksIG1heF90cmVlZGVwdGggPSAxMCksCiAgICAgICBmaWxlID0gIkZpdHMvZXh0aW5jdGlvbl9tb2RlbF9tb3J0YWxpdHkiKQoKZXh0aW5jdGlvbl9tb2RlbF9zbSA8LSBhZGRfY3JpdGVyaW9uKGV4dGluY3Rpb25fbW9kZWxfc20sIGNyaXRlcmlvbiA9ICJsb28iKQoKIyB0aGUgbW9kZWwgZG9lcyBub3QgY29udmVyZ2Ugd2hlbiB3ZSB0cnkgYW5kIGZpdCBhIHRyZWF0bWVudCAqIGJsb2NrIGludGVyYWN0aW9uCgpleHRpbmN0aW9uX21vZGVsX21tIDwtCiAgYnJtKGRhdGEgPSBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQsCiAgICAgIGZhbWlseSA9IHdlaWJ1bGwsCiAgICAgIGJmKEdlbnNfdG9fZXh0aW5jdCB8IGNlbnMoQ2Vuc29yZWQpIH4gMSArIEV2b2x1dGlvbl90cmVhdG1lbnQgKyBCbG9jayArICgxfG1tKE1vdGhlcl9zdHJhaW4sIEZhdGhlcl9zdHJhaW4pKSwKICAgICAgc2hhcGUgfiAxICsgRXZvbHV0aW9uX3RyZWF0bWVudCArIEJsb2NrKSwKICAgICAgcHJpb3IgPSBjKHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSBJbnRlcmNlcHQpLCAKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSBiKSwKICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSBiLCBkcGFyID0gc2hhcGUpKSwgCiAgICAgIGl0ZXIgPSA4MDAwLCB3YXJtdXAgPSA0MDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsCiAgICAgIHNlZWQgPSAxLCBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOSwgbWF4X3RyZWVkZXB0aCA9IDE1KSwKICAgICAgZmlsZSA9ICJGaXRzL2V4dGluY3Rpb25fbW9kZWxfbW0iKQoKZXh0aW5jdGlvbl9tb2RlbF9tbSA8LSBhZGRfY3JpdGVyaW9uKGV4dGluY3Rpb25fbW9kZWxfbW0sIGNyaXRlcmlvbiA9ICJsb28iKQoKYGBgCgokfiQKCiMjIE1vZGVsIGRpYWdub3N0aWNzCgokfiQKCkNvbXBhcmUgbW9kZWxzIHVzaW5nIGBMT09gLCBhIGJheWVzaWFuIGluZm9ybWF0aW9uIGNyaXRlcmlhCgpgYGB7cn0KbG9vX2NvbXBhcmUoZXh0aW5jdGlvbl9tb2RlbF9zbSwgZXh0aW5jdGlvbl9tb2RlbF9tbSkgICU+JSAKICBrYWJsZShkaWdpdHMgPSAzKSAlPiUgCiAga2FibGVfc3R5bGluZygpCmBgYAoKVGhlIHNpbmdsZS1tZW1iZXJzaGlwIG1vZGVsIHBlcmZvcm1zICpzbGlnaHRseSogYmV0dGVyLiBXZSBwcmVzZW50IHJlc3VsdHMgZnJvbSB0aGlzIG1vZGVsLgoKTGV0cyBzZWUgaG93IHRoZSBtb2RlbCByZWNhcGl0dWxhdGVzIHRoZSBkYXRhCgpgYGB7cn0KcHBfY2hlY2soZXh0aW5jdGlvbl9tb2RlbF9zbSwgdHlwZSA9ICJoaXN0IiwgbmRyYXdzID0gMTEsIGJpbndpZHRoID0gMSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgokfiQKCiMjIEludGVycHJldGluZyBtb2RlbCBvdXRwdXQKCiR+JAoKV2UgY2FuIGluaXRpYWxseSBpZ25vcmUgdGhlIGBzaGFwZWAgcGFyYW1ldGVyIGFuZCBmaW5kIHRoZSBtZWFuIHJhdGUgb2YgZXh0aW5jdGlvbiwgYXZlcmFnZWQgYWNyb3NzIGFsbCBnZW5lcmF0aW9ucywgdXNpbmcgdGhlIGVxdWF0aW9uCgokXGxhbWJkYT0gXGZyYWN7MX17ZV5cbXV9JAoKRmlyc3QgZmluZCBkaXN0cmlidXRpb25zIG9mICRcbXUkIGZvciBlYWNoIG9mIHRoZSB0aHJlZSB0cmVhdG1lbnRzLgoKYGBge3J9CgppbnZlcnNlX3JhdGVfd2VpYnVsbCA8LQogIGV4dGluY3Rpb25fbW9kZWxfc20gJT4lIAogIGFzX2RyYXdzX2RmKCkgJT4lIAogIHRyYW5zbXV0ZShgQ29udHJvbCBCMWAgPSBiX0ludGVyY2VwdCwgCiAgICAgICAgIGBGZW1hbGVfbGltaXRlZCBCMWAgPSBiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudEZlbWFsZSwKICAgICAgICAgYE1hbGVfbGltaXRlZCBCMWAgPSBiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudE1hbGUsCiAgICAgICAgIGBDb250cm9sIEIyYCA9IGJfSW50ZXJjZXB0ICsgYl9CbG9jazIsIAogICAgICAgICBgRmVtYWxlX2xpbWl0ZWQgQjJgID0gYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRGZW1hbGUgKyBiX0Jsb2NrMiwKICAgICAgICAgYE1hbGVfbGltaXRlZCBCMmAgPSBiX0ludGVyY2VwdCArIGJfRXZvbHV0aW9uX3RyZWF0bWVudE1hbGUgKyBiX0Jsb2NrMikKCmBgYAoKTm93IGxldHMgcGx1ZyB0aGVzZSBkaXN0cmlidXRpb25zIGludG8gdGhlIGVxdWF0aW9uIHRvIGZpbmQgbWVhbiBlc3RpbWF0ZXMgb2YgJFxsYW1iZGEkLgoKYGBge3J9CiAgaW52ZXJzZV9yYXRlX3dlaWJ1bGwgJT4lIAogIG11dGF0ZShhY3Jvc3MoMTo2LCB+MSAvIGV4cCgueCkpKSAlPiUgCiAgbXV0YXRlKGFjcm9zcyhldmVyeXRoaW5nKCksIH5tZWFuKC54KSkpICU+JSAKICBkaXN0aW5jdCgpCmBgYAoKVGhpcyBpcyB0aGUgcmF0ZSBvZiBleHRpbmN0aW9uIHBlciBnZW5lcmF0aW9uLCBhdmVyYWdlZCBhY3Jvc3MgYWxsIGdlbmVyYXRpb25zLiBIb3dldmVyLCB0aGUgd2VpYnVsbCBmYW1pbHkgYWxsb3dzIGEgZHluYW1pYyByYXRlIHJhdGhlciB0aGUgdGhlIGNvbnN0YW50IHJhdGUgdGhhdCB0aGUgZXhwb25lbnRpYWwgY29uc3RyYWlucyBpdCB0by4KCkZvbGxvd2luZyB0aGlzIFtwb3N0XShodHRwczovL2Rpc2NvdXJzZS5tYy1zdGFuLm9yZy90L2VzdGltYXRpbmctc3Vydml2YWwtY3VydmVzLXdpdGgtd2VpYnVsbGwtbW9kZWwvNjQ3NS8yKSwgdGhlIHdlaWJ1bGwgc3Vydml2YWwgZnVuY3Rpb24gY2FuIGJlIGZvdW5kIHVzaW5nIHRoZSBmb2xsb3dpbmcgdHJhbnNmb3JtYXRpb246CgokXGxhbWJkYT0gXGZyYWN7ZV5cbXV9e1xnYW1tYSgxICsgXGZyYWN7MX17a30pfSQKCndoZXJlICRrJCBpcyB0aGUgc2hhcGUgcGFyYW1ldGVyIGVzdGltYXRlZCBpbiBgYnJtc2AKClRoZW4gd2UgY2FuIGZpbmQgc3Vydml2YWwgYXQgZ2VuZXJhdGlvbiAkdCQgdXNpbmcKCiRTID0gZV57LShcZnJhY3t0fXtcbGFtYmRhfSlea30kCgpXZSBwbHVnIGluIGEgdmVjdG9yIHdpdGggMTYwMDAgZHJhd3MgZnJvbSB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBmb3IgMSkgXG11IG9mIGVhY2ggaW5oZXJpdGFuY2UgdHJlYXRtZW50IGFuZCAyKSAkayQgdGhlIHNoYXBlIHBhcmFtZXRlciB0byBmaW5kIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIHByb3BvcnRpb24gb2Ygc3Vydml2aW5nIGxpbmVhZ2VzIGF0IGVhY2ggZ2VuZXJhdGlvbi4KCmBgYHtyfQoKIyBGaW5kIGxhbWJkYSBmb3IgdGhlIHRocmVlIHRyZWF0bWVudHMuIAoKbGFtYmRhX3dlaWJ1bGwgPC0KICBleHRpbmN0aW9uX21vZGVsX3NtICU+JSAKICBhc19kcmF3c19kZigpICU+JSAKICB0cmFuc211dGUoYENvbnRyb2wgQjFgID0gYl9JbnRlcmNlcHQsIAogICAgICAgICAgICBgRmVtYWxlX2xpbWl0ZWQgQjFgID0gYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRGZW1hbGUsCiAgICAgICAgICAgIGBNYWxlX2xpbWl0ZWQgQjFgID0gYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRNYWxlLAogICAgICAgICAgICBgQ29udHJvbCBCMmAgPSBiX0ludGVyY2VwdCArIGJfQmxvY2syLCAKICAgICAgICAgICAgYEZlbWFsZV9saW1pdGVkIEIyYCA9IGJfSW50ZXJjZXB0ICsgYl9Fdm9sdXRpb25fdHJlYXRtZW50RmVtYWxlICsgYl9CbG9jazIsCiAgICAgICAgICAgIGBNYWxlX2xpbWl0ZWQgQjJgID0gYl9JbnRlcmNlcHQgKyBiX0V2b2x1dGlvbl90cmVhdG1lbnRNYWxlICsgYl9CbG9jazIsCiAgICAgICAgICAgIHNoYXBlX2NvbnRyb2xfQjEgPSBleHAoYl9zaGFwZV9JbnRlcmNlcHQpLAogICAgICAgICAgICBzaGFwZV9mZW1hbGVfQjEgPSBleHAoYl9zaGFwZV9JbnRlcmNlcHQgKyBiX3NoYXBlX0V2b2x1dGlvbl90cmVhdG1lbnRGZW1hbGUpLAogICAgICAgICAgICBzaGFwZV9tYWxlX0IxID0gZXhwKGJfc2hhcGVfSW50ZXJjZXB0ICsgYl9zaGFwZV9Fdm9sdXRpb25fdHJlYXRtZW50TWFsZSksCiAgICAgICAgICAgIHNoYXBlX2NvbnRyb2xfQjIgPSBleHAoYl9zaGFwZV9JbnRlcmNlcHQgKyBiX3NoYXBlX0Jsb2NrMiksCiAgICAgICAgICAgIHNoYXBlX2ZlbWFsZV9CMiA9IGV4cChiX3NoYXBlX0ludGVyY2VwdCArIGJfc2hhcGVfRXZvbHV0aW9uX3RyZWF0bWVudEZlbWFsZSArIGJfc2hhcGVfQmxvY2syKSwKICAgICAgICAgICAgc2hhcGVfbWFsZV9CMiA9IGV4cChiX3NoYXBlX0ludGVyY2VwdCArIGJfc2hhcGVfRXZvbHV0aW9uX3RyZWF0bWVudE1hbGUgKyBiX3NoYXBlX0Jsb2NrMikpICU+JSAKICBtdXRhdGUoQ29udHJvbF9sYW1iZGFfQjEgPSBleHAoYENvbnRyb2wgQjFgKSAvIGdhbW1hKDEgKyAxL3NoYXBlX2NvbnRyb2xfQjEpLAogICAgICAgICBGZW1hbGVfbGFtYmRhX0IxID0gZXhwKGBGZW1hbGVfbGltaXRlZCBCMWApIC8gZ2FtbWEoMSArIDEvc2hhcGVfZmVtYWxlX0IxKSwKICAgICAgICAgTWFsZV9sYW1iZGFfQjEgPSBleHAoYE1hbGVfbGltaXRlZCBCMWApIC8gZ2FtbWEoMSArIDEvc2hhcGVfbWFsZV9CMSksCiAgICAgICAgIENvbnRyb2xfbGFtYmRhX0IyID0gZXhwKGBDb250cm9sIEIyYCkgLyBnYW1tYSgxICsgMS9zaGFwZV9jb250cm9sX0IyKSwKICAgICAgICAgRmVtYWxlX2xhbWJkYV9CMiA9IGV4cChgRmVtYWxlX2xpbWl0ZWQgQjJgKSAvIGdhbW1hKDEgKyAxL3NoYXBlX2ZlbWFsZV9CMiksCiAgICAgICAgIE1hbGVfbGFtYmRhX0IyID0gZXhwKGBNYWxlX2xpbWl0ZWQgQjJgKSAvIGdhbW1hKDEgKyAxL3NoYXBlX21hbGVfQjIpKSAlPiUgCiAgc2VsZWN0KGNvbnRhaW5zKGMoImxhbWJkYSIsICJzaGFwZSIpKSkKCiMgTm93IGZpbmQgc3Vydml2YWwgcHJvcG9ydGlvbiBhdCBnZW5lcmF0aW9ucyAxLTI5CgpXZWlidWxsX3N1cnZpdmFsX2N1cnZlIDwtIAogIGxhbWJkYV93ZWlidWxsICU+JSAKICBtdXRhdGUoI0Jsb2NrIDEKICAgIENvbnRyb2xfMF9CMSAgPSBleHAoLSgwL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwgIAogICAgQ29udHJvbF8xX0IxICA9IGV4cCgtKDEvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yX0IxICA9IGV4cCgtKDIvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8zX0IxICA9IGV4cCgtKDMvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF80X0IxICA9IGV4cCgtKDQvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF81X0IxICA9IGV4cCgtKDUvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF82X0IxICA9IGV4cCgtKDYvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF83X0IxICA9IGV4cCgtKDcvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF84X0IxID0gZXhwKC0oOC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzlfQjEgPSBleHAoLSg5L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMTBfQjEgPSBleHAoLSgxMC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzExX0IxID0gZXhwKC0oMTEvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xMl9CMSA9IGV4cCgtKDEyL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMTNfQjEgPSBleHAoLSgxMy9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzE0X0IxID0gZXhwKC0oMTQvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xNV9CMSA9IGV4cCgtKDE1L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMTZfQjEgPSBleHAoLSgxNi9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzE3X0IxID0gZXhwKC0oMTcvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8xOF9CMSA9IGV4cCgtKDE4L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMTlfQjEgPSBleHAoLSgxOS9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzIwX0IxID0gZXhwKC0oMjAvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yMV9CMSA9IGV4cCgtKDIxL0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjJfQjEgPSBleHAoLSgyMi9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzIzX0IxID0gZXhwKC0oMjMvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yNF9CMSA9IGV4cCgtKDI0L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjVfQjEgPSBleHAoLSgyNS9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzI2X0IxID0gZXhwKC0oMjYvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgQ29udHJvbF8yN19CMSA9IGV4cCgtKDI3L0NvbnRyb2xfbGFtYmRhX0IxKV5zaGFwZV9jb250cm9sX0IxKSwKICAgIENvbnRyb2xfMjhfQjEgPSBleHAoLSgyOC9Db250cm9sX2xhbWJkYV9CMSlec2hhcGVfY29udHJvbF9CMSksCiAgICBDb250cm9sXzI5X0IxID0gZXhwKC0oMjkvQ29udHJvbF9sYW1iZGFfQjEpXnNoYXBlX2NvbnRyb2xfQjEpLAogICAgRmVtYWxlXzBfQjEgID0gZXhwKC0oMC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzFfQjEgID0gZXhwKC0oMS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzJfQjEgID0gZXhwKC0oMi9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzNfQjEgID0gZXhwKC0oMy9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzRfQjEgID0gZXhwKC0oNC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzVfQjEgID0gZXhwKC0oNS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzZfQjEgID0gZXhwKC0oNi9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzdfQjEgID0gZXhwKC0oNy9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzhfQjEgID0gZXhwKC0oOC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzlfQjEgID0gZXhwKC0oOS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzEwX0IxICA9IGV4cCgtKDEwL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMTFfQjEgID0gZXhwKC0oMTEvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xMl9CMSAgPSBleHAoLSgxMi9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzEzX0IxICA9IGV4cCgtKDEzL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMTRfQjEgID0gZXhwKC0oMTQvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xNV9CMSAgPSBleHAoLSgxNS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzE2X0IxICA9IGV4cCgtKDE2L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMTdfQjEgID0gZXhwKC0oMTcvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8xOF9CMSAgPSBleHAoLSgxOC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzE5X0IxICA9IGV4cCgtKDE5L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjBfQjEgID0gZXhwKC0oMjAvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yMV9CMSA9IGV4cCgtKDIxL0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjJfQjEgPSBleHAoLSgyMi9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzIzX0IxID0gZXhwKC0oMjMvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yNF9CMSA9IGV4cCgtKDI0L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjVfQjEgPSBleHAoLSgyNS9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzI2X0IxID0gZXhwKC0oMjYvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIEZlbWFsZV8yN19CMSA9IGV4cCgtKDI3L0ZlbWFsZV9sYW1iZGFfQjEpXnNoYXBlX2ZlbWFsZV9CMSksCiAgICBGZW1hbGVfMjhfQjEgPSBleHAoLSgyOC9GZW1hbGVfbGFtYmRhX0IxKV5zaGFwZV9mZW1hbGVfQjEpLAogICAgRmVtYWxlXzI5X0IxID0gZXhwKC0oMjkvRmVtYWxlX2xhbWJkYV9CMSlec2hhcGVfZmVtYWxlX0IxKSwKICAgIE1hbGVfMF9CMSAgICAgPSBleHAoLSgwL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMV9CMSAgICAgPSBleHAoLSgxL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMl9CMSAgICAgPSBleHAoLSgyL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfM19CMSAgICAgPSBleHAoLSgzL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfNF9CMSAgICAgPSBleHAoLSg0L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfNV9CMSAgICAgPSBleHAoLSg1L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfNl9CMSAgICAgPSBleHAoLSg2L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfN19CMSAgICAgPSBleHAoLSg3L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfOF9CMSAgICAgPSBleHAoLSg4L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfOV9CMSAgICAgPSBleHAoLSg5L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMTBfQjEgICAgPSBleHAoLSgxMC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzExX0IxICAgID0gZXhwKC0oMTEvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xMl9CMSAgICA9IGV4cCgtKDEyL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMTNfQjEgICAgPSBleHAoLSgxMy9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzE0X0IxICAgID0gZXhwKC0oMTQvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xNV9CMSAgICA9IGV4cCgtKDE1L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMTZfQjEgICAgPSBleHAoLSgxNi9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzE3X0IxICAgID0gZXhwKC0oMTcvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8xOF9CMSAgICA9IGV4cCgtKDE4L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMTlfQjEgICAgPSBleHAoLSgxOS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzIwX0IxICAgID0gZXhwKC0oMjAvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yMV9CMSA9IGV4cCgtKDIxL01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjJfQjEgPSBleHAoLSgyMi9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzIzX0IxID0gZXhwKC0oMjMvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yNF9CMSA9IGV4cCgtKDI0L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjVfQjEgPSBleHAoLSgyNS9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzI2X0IxID0gZXhwKC0oMjYvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgTWFsZV8yN19CMSA9IGV4cCgtKDI3L01hbGVfbGFtYmRhX0IxKV5zaGFwZV9tYWxlX0IxKSwKICAgIE1hbGVfMjhfQjEgPSBleHAoLSgyOC9NYWxlX2xhbWJkYV9CMSlec2hhcGVfbWFsZV9CMSksCiAgICBNYWxlXzI5X0IxID0gZXhwKC0oMjkvTWFsZV9sYW1iZGFfQjEpXnNoYXBlX21hbGVfQjEpLAogICAgIyBCbG9jayAyCiAgICBDb250cm9sXzBfQjIgID0gZXhwKC0oMC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksICAKICAgIENvbnRyb2xfMV9CMiAgPSBleHAoLSgxL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMl9CMiAgPSBleHAoLSgyL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfM19CMiAgPSBleHAoLSgzL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfNF9CMiAgPSBleHAoLSg0L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfNV9CMiAgPSBleHAoLSg1L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfNl9CMiAgPSBleHAoLSg2L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfN19CMiAgPSBleHAoLSg3L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfOF9CMiA9IGV4cCgtKDgvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF85X0IyID0gZXhwKC0oOS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzEwX0IyID0gZXhwKC0oMTAvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xMV9CMiA9IGV4cCgtKDExL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMTJfQjIgPSBleHAoLSgxMi9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzEzX0IyID0gZXhwKC0oMTMvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xNF9CMiA9IGV4cCgtKDE0L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMTVfQjIgPSBleHAoLSgxNS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzE2X0IyID0gZXhwKC0oMTYvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8xN19CMiA9IGV4cCgtKDE3L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMThfQjIgPSBleHAoLSgxOC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzE5X0IyID0gZXhwKC0oMTkvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yMF9CMiA9IGV4cCgtKDIwL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjFfQjIgPSBleHAoLSgyMS9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzIyX0IyID0gZXhwKC0oMjIvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yM19CMiA9IGV4cCgtKDIzL0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjRfQjIgPSBleHAoLSgyNC9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzI1X0IyID0gZXhwKC0oMjUvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yNl9CMiA9IGV4cCgtKDI2L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIENvbnRyb2xfMjdfQjIgPSBleHAoLSgyNy9Db250cm9sX2xhbWJkYV9CMilec2hhcGVfY29udHJvbF9CMiksCiAgICBDb250cm9sXzI4X0IyID0gZXhwKC0oMjgvQ29udHJvbF9sYW1iZGFfQjIpXnNoYXBlX2NvbnRyb2xfQjIpLAogICAgQ29udHJvbF8yOV9CMiA9IGV4cCgtKDI5L0NvbnRyb2xfbGFtYmRhX0IyKV5zaGFwZV9jb250cm9sX0IyKSwKICAgIEZlbWFsZV8wX0IyICA9IGV4cCgtKDAvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xX0IyICA9IGV4cCgtKDEvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yX0IyICA9IGV4cCgtKDIvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8zX0IyICA9IGV4cCgtKDMvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV80X0IyICA9IGV4cCgtKDQvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV81X0IyICA9IGV4cCgtKDUvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV82X0IyICA9IGV4cCgtKDYvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV83X0IyICA9IGV4cCgtKDcvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV84X0IyICA9IGV4cCgtKDgvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV85X0IyICA9IGV4cCgtKDkvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xMF9CMiAgPSBleHAoLSgxMC9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzExX0IyICA9IGV4cCgtKDExL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTJfQjIgID0gZXhwKC0oMTIvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xM19CMiAgPSBleHAoLSgxMy9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzE0X0IyICA9IGV4cCgtKDE0L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMTVfQjIgID0gZXhwKC0oMTUvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xNl9CMiAgPSBleHAoLSgxNi9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzE3X0IyICA9IGV4cCgtKDE3L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMThfQjIgID0gZXhwKC0oMTgvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8xOV9CMiAgPSBleHAoLSgxOS9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzIwX0IyICA9IGV4cCgtKDIwL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjFfQjIgPSBleHAoLSgyMS9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzIyX0IyID0gZXhwKC0oMjIvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yM19CMiA9IGV4cCgtKDIzL0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjRfQjIgPSBleHAoLSgyNC9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzI1X0IyID0gZXhwKC0oMjUvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yNl9CMiA9IGV4cCgtKDI2L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBGZW1hbGVfMjdfQjIgPSBleHAoLSgyNy9GZW1hbGVfbGFtYmRhX0IyKV5zaGFwZV9mZW1hbGVfQjIpLAogICAgRmVtYWxlXzI4X0IyID0gZXhwKC0oMjgvRmVtYWxlX2xhbWJkYV9CMilec2hhcGVfZmVtYWxlX0IyKSwKICAgIEZlbWFsZV8yOV9CMiA9IGV4cCgtKDI5L0ZlbWFsZV9sYW1iZGFfQjIpXnNoYXBlX2ZlbWFsZV9CMiksCiAgICBNYWxlXzBfQjIgICAgID0gZXhwKC0oMC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzFfQjIgICAgID0gZXhwKC0oMS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzJfQjIgICAgID0gZXhwKC0oMi9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzNfQjIgICAgID0gZXhwKC0oMy9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzRfQjIgICAgID0gZXhwKC0oNC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzVfQjIgICAgID0gZXhwKC0oNS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzZfQjIgICAgID0gZXhwKC0oNi9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzdfQjIgICAgID0gZXhwKC0oNy9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzhfQjIgICAgID0gZXhwKC0oOC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzlfQjIgICAgID0gZXhwKC0oOS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzEwX0IyICAgID0gZXhwKC0oMTAvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xMV9CMiAgICA9IGV4cCgtKDExL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMTJfQjIgICAgPSBleHAoLSgxMi9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzEzX0IyICAgID0gZXhwKC0oMTMvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xNF9CMiAgICA9IGV4cCgtKDE0L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMTVfQjIgICAgPSBleHAoLSgxNS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzE2X0IyICAgID0gZXhwKC0oMTYvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8xN19CMiAgICA9IGV4cCgtKDE3L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMThfQjIgICAgPSBleHAoLSgxOC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzE5X0IyICAgID0gZXhwKC0oMTkvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yMF9CMiAgICA9IGV4cCgtKDIwL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjFfQjIgPSBleHAoLSgyMS9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzIyX0IyID0gZXhwKC0oMjIvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yM19CMiA9IGV4cCgtKDIzL01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjRfQjIgPSBleHAoLSgyNC9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzI1X0IyID0gZXhwKC0oMjUvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yNl9CMiA9IGV4cCgtKDI2L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSwKICAgIE1hbGVfMjdfQjIgPSBleHAoLSgyNy9NYWxlX2xhbWJkYV9CMilec2hhcGVfbWFsZV9CMiksCiAgICBNYWxlXzI4X0IyID0gZXhwKC0oMjgvTWFsZV9sYW1iZGFfQjIpXnNoYXBlX21hbGVfQjIpLAogICAgTWFsZV8yOV9CMiA9IGV4cCgtKDI5L01hbGVfbGFtYmRhX0IyKV5zaGFwZV9tYWxlX0IyKSkgJT4lIAogIHNlbGVjdCgtYyhjb250YWlucyhjKCJzaGFwZSIsICJsYW1iZGEiKSkpKQoKV2VpYnVsbF9leHRpbmN0aW9uX2VzdGltYXRlc19sb25nIDwtCiAgV2VpYnVsbF9zdXJ2aXZhbF9jdXJ2ZSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gIkV2b2x1dGlvbiB0cmVhdG1lbnQiLCB2YWx1ZXNfdG8gPSAiUHJvcF9saW5lYWdlc19zdXJ2aXZpbmciKSAlPiUgCiAgc2VwYXJhdGUoYEV2b2x1dGlvbiB0cmVhdG1lbnRgLCBpbnRvID0gYygiRXZvbHV0aW9uIHRyZWF0bWVudCIsICJHZW5lcmF0aW9uIiwgIkJsb2NrIiksIHNlcCA9ICJfIikgJT4lIAogICAgbXV0YXRlKGBFdm9sdXRpb24gdHJlYXRtZW50YCA9IGNhc2Vfd2hlbigKICAgIGBFdm9sdXRpb24gdHJlYXRtZW50YCA9PSAiRmVtYWxlIiB+ICJGZW1hbGUtbGltaXRlZCIsCiAgICBgRXZvbHV0aW9uIHRyZWF0bWVudGAgPT0gIk1hbGUiIH4gIk1hbGUtbGltaXRlZCIsCiAgICBgRXZvbHV0aW9uIHRyZWF0bWVudGAgPT0gIkNvbnRyb2wiIH4gIkNvbnRyb2wiCiAgKSkKCmBgYAoKJH4kCgojIyBDcmVhdGUgRmlndXJlIDEKCk1ha2UgcGFuZWwgYSBvZiBGaWd1cmUgMQoKYGBge3J9CiMgQmxvY2sgMQoKd2VpYnVsbF9zdXJ2X3Bsb3RfQjEgPC0gCiAgV2VpYnVsbF9leHRpbmN0aW9uX2VzdGltYXRlc19sb25nICU+JSAKICBmaWx0ZXIoQmxvY2sgPT0gIkIxIikgJT4lIAogIGdyb3VwX2J5KGBFdm9sdXRpb24gdHJlYXRtZW50YCwgR2VuZXJhdGlvbikgJT4lIAogIHRpZHliYXllczo6bWVkaWFuX3FpKFByb3BfbGluZWFnZXNfc3Vydml2aW5nLCAud2lkdGggPSAwLjUpICU+JSAKICBtdXRhdGUoR2VuZXJhdGlvbiA9IGFzLm51bWVyaWMoR2VuZXJhdGlvbikpICU+JSAKICBhcnJhbmdlKEdlbmVyYXRpb24pICU+JSAKICAjIHBsb3QhCiAgZ2dwbG90KGFlcyh4ID0gR2VuZXJhdGlvbikpICsKICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IC5sb3dlciwgeW1heCA9IC51cHBlciwgZmlsbCA9IGBFdm9sdXRpb24gdHJlYXRtZW50YCksCiAgICAgICAgICAgICAgYWxwaGEgPSAxLzIpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBQcm9wX2xpbmVhZ2VzX3N1cnZpdmluZywgY29sb3IgPSBgRXZvbHV0aW9uIHRyZWF0bWVudGApLCBsaW5ldHlwZSA9NSwgbGluZXdpZHRoID0gMC44KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMykpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMyksIGd1aWRlID0gIm5vbmUiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgNSwgMTAsIDE1LCAyMCwgMjUsIDMwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsIDAuMjUsIC41LCAwLjc1LCAxKSwgbGltaXRzID0gMDoxKSArCiAgbGFicyh4ID0gIkdlbmVyYXRpb25zIG9mIGluYnJlZWRpbmciLCB5ID0gIlByb3BvcnRpb24gb2Ygc3VydmluZyBsaW5lYWdlcyIsIGZpbGwgPSAiU2VsZWN0aW9uIHJlc3BvbnNlXG5oaXN0b3J5IikgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBwYW5lbCBiZwogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcsIGNvbG9yPU5BKSwgI3RyYW5zcGFyZW50IHBsb3QgYmcKICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcpLCAjdHJhbnNwYXJlbnQgbGVnZW5kIGJnCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3VyID0gJ3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKC45NSwgLjk1KSwKICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoInJpZ2h0IiwgInRvcCIpLAogICAgICAgIGxlZ2VuZC5ib3guanVzdCA9ICJyaWdodCIsCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbig2LCA2LCA2LCA2KSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSkKCmBgYAoKV2UgY2FuIGFsc28gcGxvdCB0aGUgbWVhbiBnZW5lcmF0aW9ucyB1bnRpbCBleHRpbmN0aW9uIGZvciBlYWNoIGV2b2x1dGlvbiB0cmVhdG1lbnQuIFNvbWUgZGF0YSB3cmFuZ2xpbmcgaXMgZmlyc3QgbmVlZGVkLgoKYGBge3J9CgpuZXdfZGF0YSA8LSBleHBhbmRfZ3JpZCgKICBFdm9sdXRpb25fdHJlYXRtZW50ID0gZXh0aW5jdGlvbl9kYXRhX3dyYW5nbGVkJEV2b2x1dGlvbl90cmVhdG1lbnQsCiAgQmxvY2sgPSAxOjIpICU+JSAKICBkaXN0aW5jdChFdm9sdXRpb25fdHJlYXRtZW50LCBCbG9jaykgJT4lCiAgbXV0YXRlKGtleSA9IHBhc3RlKCJWIiwgMTpuKCksIHNlcCA9ICIiKSkKCndlaWJ1bGxfZXN0aW1hdGVzIDwtIAogIGZpdHRlZChleHRpbmN0aW9uX21vZGVsX3NtLCBuZXdkYXRhID0gbmV3X2RhdGEsCiAgICAgICAgIHJlX2Zvcm11bGEgPSBOQSwgc3VtbWFyeSA9IEYpICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgcmVuYW1lKGBGZW1hbGUtbGltaXRlZF8xYCA9IFYxLCBgRmVtYWxlLWxpbWl0ZWRfMmAgPSBWMiwgYE1hbGUtbGltaXRlZF8xYCA9IFYzLCBgTWFsZS1saW1pdGVkXzJgID0gVjQsIENvbnRyb2xfMSA9IFY1LCBDb250cm9sXzIgPSBWNikKCm1lYW5fd2VpYnVsbF9lc3RpbWF0ZXMgPC0gCiAgd2VpYnVsbF9lc3RpbWF0ZXMgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gMTo2LCBuYW1lc190byA9ICJFdm9sdXRpb24gdHJlYXRtZW50IiwgdmFsdWVzX3RvID0gImdlbmVyYXRpb25zIikgJT4lIAogIHNlcGFyYXRlKGNvbCA9IGBFdm9sdXRpb24gdHJlYXRtZW50YCwgaW50byA9IGMoIkV2b2x1dGlvbiB0cmVhdG1lbnQiLCAiQmxvY2siKSwgc2VwID0gIl8iKQoKCiMgY2FsY3VsYXRlIGNvbnRyYXN0cwoKd2VpYnVsbF9jb250cmFzdHNfQjEgPC0KICB3ZWlidWxsX2VzdGltYXRlcyAlPiUgCiAgbXV0YXRlKGBGZW1hbGUgLSBDb250cm9sYCA9IGBGZW1hbGUtbGltaXRlZF8xYCAtIENvbnRyb2xfMSwKICAgICAgICAgYE1hbGUgLSBGZW1hbGVgID0gYE1hbGUtbGltaXRlZF8xYCAtIGBGZW1hbGUtbGltaXRlZF8xYCwKICAgICAgICAgYE1hbGUgLSBDb250cm9sYCA9IGBNYWxlLWxpbWl0ZWRfMWAgLSBDb250cm9sXzEpICU+JSAKICBzZWxlY3QoLWMoYE1hbGUtbGltaXRlZF8xYCwgQ29udHJvbF8xLCBgRmVtYWxlLWxpbWl0ZWRfMWAsCiAgICAgICAgICAgIGBNYWxlLWxpbWl0ZWRfMmAsIENvbnRyb2xfMiwgYEZlbWFsZS1saW1pdGVkXzJgKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gMTozLCBuYW1lc190byA9ICJDb250cmFzdCIsIHZhbHVlc190byA9ICJnZW5lcmF0aW9uX2RpZmYiKQoKd2VpYnVsbF9jb250cmFzdHNfQjIgPC0KICB3ZWlidWxsX2VzdGltYXRlcyAlPiUgCiAgbXV0YXRlKGBGZW1hbGUgLSBDb250cm9sYCA9IGBGZW1hbGUtbGltaXRlZF8yYCAtIENvbnRyb2xfMiwKICAgICAgICAgYE1hbGUgLSBGZW1hbGVgID0gYE1hbGUtbGltaXRlZF8yYCAtIGBGZW1hbGUtbGltaXRlZF8yYCwKICAgICAgICAgYE1hbGUgLSBDb250cm9sYCA9IGBNYWxlLWxpbWl0ZWRfMmAgLSBDb250cm9sXzIpICU+JSAKICBzZWxlY3QoLWMoYE1hbGUtbGltaXRlZF8xYCwgQ29udHJvbF8xLCBgRmVtYWxlLWxpbWl0ZWRfMWAsCiAgICAgICAgICAgIGBNYWxlLWxpbWl0ZWRfMmAsIENvbnRyb2xfMiwgYEZlbWFsZS1saW1pdGVkXzJgKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gMTozLCBuYW1lc190byA9ICJDb250cmFzdCIsIHZhbHVlc190byA9ICJnZW5lcmF0aW9uX2RpZmYiKQpgYGAKCkNyZWF0ZSBwYW5lbHMgYiBhbmQgYyBvZiBGaWd1cmUgMQoKYGBge3J9CiMgcGxvdCB0aGUgbWVhbnMKCiMgYmxvY2sgMQoKZXh0X3AxX0IxIDwtIAogIG1lYW5fd2VpYnVsbF9lc3RpbWF0ZXMgJT4lIAogIGZpbHRlcihCbG9jayA9PSAiMSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBnZW5lcmF0aW9ucywgeSA9IGBFdm9sdXRpb24gdHJlYXRtZW50YCkpICsKICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBgRXZvbHV0aW9uIHRyZWF0bWVudGApLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwKICAgICAgICAgICAgICAgc2xhYl9jb2xvdXIgPSAiYmxhY2siLCBzbGFiX3NpemUgPSAwLjgpICsgIyB3aWR0aCBpbmRpY2F0ZXMgdGhlIHVuY2VydGFpbnR5IGludGVydmFsczogaGVyZSB3ZSBoYXZlIDY2JSBhbmQgOTUlIGludGVydmFscyArICMgd2lkdGggaW5kaWNhdGVzIHRoZSB1bmNlcnRhaW50eSBpbnRlcnZhbHM6IGhlcmUgd2UgaGF2ZSA2NiUgYW5kIDk1JSBpbnRlcnZhbHMrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgNSkpICsKICBsYWJzKHggPSAiTWVhbiBnZW5lcmF0aW9ucyB0aWxsIGV4dGluY3Rpb24iLCB5ID0gIlNlbGVjdGlvbiByZXNwb25zZSBoaXN0b3J5IikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDQsIDEyLCAxKSkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBwYW5lbCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCgojIHBsb3QgdGhlIGNvbnRyYXN0cwoKZXh0X3AyX0IxIDwtIAogIHdlaWJ1bGxfY29udHJhc3RzX0IxICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBnZW5lcmF0aW9uX2RpZmYsIHkgPSBmY3RfcmVsZXZlbChDb250cmFzdCwgIkZlbWFsZSAtIENvbnRyb2wiLCAiTWFsZSAtIEZlbWFsZSIsICJNYWxlIC0gQ29udHJvbCIpKSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IENvbnRyYXN0KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAxLAogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUsCiAgICAgICAgICAgICAgIHNsYWJfY29sb3VyID0gImJsYWNrIiwgc2xhYl9zaXplID0gMC44KSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoY2FydG9fcGFsKDcsICJQZWFjaCIpWzJdLCBjYXJ0b19wYWwoNywgIlB1cnAiKVsxXSwgY2FydG9fcGFsKDcsICJUZWFsR3JuIilbMV0pKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyLCBjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJEaWZmLiBpbiBnZW5lcmF0aW9ucyB0aWxsIGV4dGluY3Rpb24iLCB5ID0gIlRyZWF0bWVudCBjb250cmFzdCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgtNCwgNiwgMikpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcpLCAjdHJhbnNwYXJlbnQgcGFuZWwgYmcKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCgpgYGAKCldlIGNhbiBhbHNvIGVzdGltYXRlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gZXZvbHV0aW9uYXJ5IHRyZWF0bWVudHMgaW4gdGhlIHByb3BvcnRpb24gb2YgbGluZWFnZXMgZXh0YW50IGluIGVhY2ggZ2VuZXJhdGlvbi4gQmVsb3cgd2UgY2FsY3VsYXRlIGVhY2ggY29udHJhc3QgYW5kIG1ha2UgcGFuZWxzIGQsIGUgYW5kIGYKCmBgYHtyfQoKIyBCbG9jayAxCgpEaWZmZXJlbmNlX2dlbnNfQjEgPC0KICBXZWlidWxsX3N1cnZpdmFsX2N1cnZlICU+JSAKICBzZWxlY3QoY29udGFpbnMoIkIxIikpICU+JSAKICBtdXRhdGUoRzFfZGlmZi5jID0gTWFsZV8xX0IxIC0gQ29udHJvbF8xX0IxLAogICAgICAgICBHMV9kaWZmLmYgPSBNYWxlXzFfQjEgLSBGZW1hbGVfMV9CMSwKICAgICAgICAgRzFfZGlmZi5mYyA9IEZlbWFsZV8xX0IxIC0gQ29udHJvbF8xX0IxLAogICAgICAgICBHMl9kaWZmLmMgPSBNYWxlXzJfQjEgLSBDb250cm9sXzJfQjEsCiAgICAgICAgIEcyX2RpZmYuZiA9IE1hbGVfMl9CMSAtIEZlbWFsZV8yX0IxLAogICAgICAgICBHMl9kaWZmLmZjID0gRmVtYWxlXzJfQjEgLSBDb250cm9sXzJfQjEsCiAgICAgICAgIEczX2RpZmYuYyA9IE1hbGVfM19CMSAtIENvbnRyb2xfM19CMSwKICAgICAgICAgRzNfZGlmZi5mID0gTWFsZV8zX0IxIC0gRmVtYWxlXzNfQjEsCiAgICAgICAgIEczX2RpZmYuZmMgPSBGZW1hbGVfM19CMSAtIENvbnRyb2xfM19CMSwKICAgICAgICAgRzRfZGlmZi5jID0gTWFsZV80X0IxIC0gQ29udHJvbF80X0IxLAogICAgICAgICBHNF9kaWZmLmYgPSBNYWxlXzRfQjEgLSBGZW1hbGVfNF9CMSwKICAgICAgICAgRzRfZGlmZi5mYyA9IEZlbWFsZV80X0IxIC0gQ29udHJvbF80X0IxLAogICAgICAgICBHNV9kaWZmLmMgPSBNYWxlXzVfQjEgLSBDb250cm9sXzVfQjEsCiAgICAgICAgIEc1X2RpZmYuZiA9IE1hbGVfNV9CMSAtIEZlbWFsZV81X0IxLAogICAgICAgICBHNV9kaWZmLmZjID0gRmVtYWxlXzVfQjEgLSBDb250cm9sXzVfQjEsCiAgICAgICAgIEc2X2RpZmYuYyA9IE1hbGVfNl9CMSAtIENvbnRyb2xfNl9CMSwKICAgICAgICAgRzZfZGlmZi5mID0gTWFsZV82X0IxIC0gRmVtYWxlXzZfQjEsCiAgICAgICAgIEc2X2RpZmYuZmMgPSBGZW1hbGVfNl9CMSAtIENvbnRyb2xfNl9CMSwKICAgICAgICAgRzdfZGlmZi5jID0gTWFsZV83X0IxIC0gQ29udHJvbF83X0IxLAogICAgICAgICBHN19kaWZmLmYgPSBNYWxlXzdfQjEgLSBGZW1hbGVfN19CMSwKICAgICAgICAgRzdfZGlmZi5mYyA9IEZlbWFsZV83X0IxIC0gQ29udHJvbF83X0IxLAogICAgICAgICBHOF9kaWZmLmMgPSBNYWxlXzhfQjEgLSBDb250cm9sXzhfQjEsCiAgICAgICAgIEc4X2RpZmYuZiA9IE1hbGVfOF9CMSAtIEZlbWFsZV84X0IxLAogICAgICAgICBHOF9kaWZmLmZjID0gRmVtYWxlXzhfQjEgLSBDb250cm9sXzhfQjEsCiAgICAgICAgIEc5X2RpZmYuYyA9IE1hbGVfOV9CMSAtIENvbnRyb2xfOV9CMSwKICAgICAgICAgRzlfZGlmZi5mID0gTWFsZV85X0IxIC0gRmVtYWxlXzlfQjEsCiAgICAgICAgIEc5X2RpZmYuZmMgPSBGZW1hbGVfOV9CMSAtIENvbnRyb2xfOV9CMSwKICAgICAgICAgRzEwX2RpZmYuYyA9IE1hbGVfMTBfQjEgLSBDb250cm9sXzEwX0IxLAogICAgICAgICBHMTBfZGlmZi5mID0gTWFsZV8xMF9CMSAtIEZlbWFsZV8xMF9CMSwKICAgICAgICAgRzEwX2RpZmYuZmMgPSBGZW1hbGVfMTBfQjEgLSBDb250cm9sXzEwX0IxLAogICAgICAgICBHMTFfZGlmZi5jID0gTWFsZV8xMV9CMSAtIENvbnRyb2xfMTFfQjEsCiAgICAgICAgIEcxMV9kaWZmLmYgPSBNYWxlXzExX0IxIC0gRmVtYWxlXzExX0IxLAogICAgICAgICBHMTFfZGlmZi5mYyA9IEZlbWFsZV8xMV9CMSAtIENvbnRyb2xfMTFfQjEsCiAgICAgICAgIEcxMl9kaWZmLmMgPSBNYWxlXzEyX0IxIC0gQ29udHJvbF8xMl9CMSwKICAgICAgICAgRzEyX2RpZmYuZiA9IE1hbGVfMTJfQjEgLSBGZW1hbGVfMTJfQjEsCiAgICAgICAgIEcxMl9kaWZmLmZjID0gRmVtYWxlXzEyX0IxIC0gQ29udHJvbF8xMl9CMSwKICAgICAgICAgRzEzX2RpZmYuYyA9IE1hbGVfMTNfQjEgLSBDb250cm9sXzEzX0IxLAogICAgICAgICBHMTNfZGlmZi5mID0gTWFsZV8xM19CMSAtIEZlbWFsZV8xM19CMSwKICAgICAgICAgRzEzX2RpZmYuZmMgPSBGZW1hbGVfMTNfQjEgLSBDb250cm9sXzEzX0IxLAogICAgICAgICBHMTRfZGlmZi5jID0gTWFsZV8xNF9CMSAtIENvbnRyb2xfMTRfQjEsCiAgICAgICAgIEcxNF9kaWZmLmYgPSBNYWxlXzE0X0IxIC0gRmVtYWxlXzE0X0IxLAogICAgICAgICBHMTRfZGlmZi5mYyA9IEZlbWFsZV8xNF9CMSAtIENvbnRyb2xfMTRfQjEsCiAgICAgICAgIEcxNV9kaWZmLmMgPSBNYWxlXzE1X0IxIC0gQ29udHJvbF8xNV9CMSwKICAgICAgICAgRzE1X2RpZmYuZiA9IE1hbGVfMTVfQjEgLSBGZW1hbGVfMTVfQjEsCiAgICAgICAgIEcxNV9kaWZmLmZjID0gRmVtYWxlXzE1X0IxIC0gQ29udHJvbF8xNV9CMSwKICAgICAgICAgRzE2X2RpZmYuYyA9IE1hbGVfMTZfQjEgLSBDb250cm9sXzE2X0IxLAogICAgICAgICBHMTZfZGlmZi5mID0gTWFsZV8xNl9CMSAtIEZlbWFsZV8xNl9CMSwKICAgICAgICAgRzE2X2RpZmYuZmMgPSBGZW1hbGVfMTZfQjEgLSBDb250cm9sXzE2X0IxLAogICAgICAgICBHMTdfZGlmZi5jID0gTWFsZV8xN19CMSAtIENvbnRyb2xfMTdfQjEsCiAgICAgICAgIEcxN19kaWZmLmYgPSBNYWxlXzE3X0IxIC0gRmVtYWxlXzE3X0IxLAogICAgICAgICBHMTdfZGlmZi5mYyA9IEZlbWFsZV8xN19CMSAtIENvbnRyb2xfMTdfQjEsCiAgICAgICAgIEcxOF9kaWZmLmMgPSBNYWxlXzE4X0IxIC0gQ29udHJvbF8xOF9CMSwKICAgICAgICAgRzE4X2RpZmYuZiA9IE1hbGVfMThfQjEgLSBGZW1hbGVfMThfQjEsCiAgICAgICAgIEcxOF9kaWZmLmZjID0gRmVtYWxlXzE4X0IxIC0gQ29udHJvbF8xOF9CMSwKICAgICAgICAgRzE5X2RpZmYuYyA9IE1hbGVfMTlfQjEgLSBDb250cm9sXzE5X0IxLAogICAgICAgICBHMTlfZGlmZi5mID0gTWFsZV8xOV9CMSAtIEZlbWFsZV8xOV9CMSwKICAgICAgICAgRzE5X2RpZmYuZmMgPSBGZW1hbGVfMTlfQjEgLSBDb250cm9sXzE5X0IxLAogICAgICAgICBHMjBfZGlmZi5jID0gTWFsZV8yMF9CMSAtIENvbnRyb2xfMjBfQjEsCiAgICAgICAgIEcyMF9kaWZmLmYgPSBNYWxlXzIwX0IxIC0gRmVtYWxlXzIwX0IxLAogICAgICAgICBHMjBfZGlmZi5mYyA9IEZlbWFsZV8yMF9CMSAtIENvbnRyb2xfMjBfQjEsCiAgICAgICAgIEcyMV9kaWZmLmMgPSBNYWxlXzIxX0IxIC0gQ29udHJvbF8yMV9CMSwKICAgICAgICAgRzIxX2RpZmYuZiA9IE1hbGVfMjFfQjEgLSBGZW1hbGVfMjFfQjEsCiAgICAgICAgIEcyMV9kaWZmLmZjID0gRmVtYWxlXzIxX0IxIC0gQ29udHJvbF8yMV9CMSwKICAgICAgICAgRzIyX2RpZmYuYyA9IE1hbGVfMjJfQjEgLSBDb250cm9sXzIyX0IxLAogICAgICAgICBHMjJfZGlmZi5mID0gTWFsZV8yMl9CMSAtIEZlbWFsZV8yMl9CMSwKICAgICAgICAgRzIyX2RpZmYuZmMgPSBGZW1hbGVfMjJfQjEgLSBDb250cm9sXzIyX0IxLAogICAgICAgICBHMjNfZGlmZi5jID0gTWFsZV8yM19CMSAtIENvbnRyb2xfMjNfQjEsCiAgICAgICAgIEcyM19kaWZmLmYgPSBNYWxlXzIzX0IxIC0gRmVtYWxlXzIzX0IxLAogICAgICAgICBHMjNfZGlmZi5mYyA9IEZlbWFsZV8yM19CMSAtIENvbnRyb2xfMjNfQjEsCiAgICAgICAgIEcyNF9kaWZmLmMgPSBNYWxlXzI0X0IxIC0gQ29udHJvbF8yNF9CMSwKICAgICAgICAgRzI0X2RpZmYuZiA9IE1hbGVfMjRfQjEgLSBGZW1hbGVfMjRfQjEsCiAgICAgICAgIEcyNF9kaWZmLmZjID0gRmVtYWxlXzI0X0IxIC0gQ29udHJvbF8yNF9CMSwKICAgICAgICAgRzI1X2RpZmYuYyA9IE1hbGVfMjVfQjEgLSBDb250cm9sXzI1X0IxLAogICAgICAgICBHMjVfZGlmZi5mID0gTWFsZV8yNV9CMSAtIEZlbWFsZV8yNV9CMSwKICAgICAgICAgRzI1X2RpZmYuZmMgPSBGZW1hbGVfMjVfQjEgLSBDb250cm9sXzI1X0IxLAogICAgICAgICBHMjZfZGlmZi5jID0gTWFsZV8yNl9CMSAtIENvbnRyb2xfMjZfQjEsCiAgICAgICAgIEcyNl9kaWZmLmYgPSBNYWxlXzI2X0IxIC0gRmVtYWxlXzI2X0IxLAogICAgICAgICBHMjZfZGlmZi5mYyA9IEZlbWFsZV8yNl9CMSAtIENvbnRyb2xfMjZfQjEsCiAgICAgICAgIEcyN19kaWZmLmMgPSBNYWxlXzI3X0IxIC0gQ29udHJvbF8yN19CMSwKICAgICAgICAgRzI3X2RpZmYuZiA9IE1hbGVfMjdfQjEgLSBGZW1hbGVfMjdfQjEsCiAgICAgICAgIEcyN19kaWZmLmZjID0gRmVtYWxlXzI3X0IxIC0gQ29udHJvbF8yN19CMSwKICAgICAgICAgRzI4X2RpZmYuYyA9IE1hbGVfMjhfQjEgLSBDb250cm9sXzI4X0IxLAogICAgICAgICBHMjhfZGlmZi5mID0gTWFsZV8yOF9CMSAtIEZlbWFsZV8yOF9CMSwKICAgICAgICAgRzI4X2RpZmYuZmMgPSBGZW1hbGVfMjhfQjEgLSBDb250cm9sXzI4X0IxLAogICAgICAgICBHMjlfZGlmZi5jID0gTWFsZV8yX0IxIC0gQ29udHJvbF8yOV9CMSwKICAgICAgICAgRzI5X2RpZmYuZiA9IE1hbGVfMjlfQjEgLSBGZW1hbGVfMjlfQjEsCiAgICAgICAgIEcyOV9kaWZmLmZjID0gRmVtYWxlXzI5X0IxIC0gQ29udHJvbF8yOV9CMSkgJT4lIAogIHNlbGVjdChzdGFydHNfd2l0aCgiRyIpKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gIkRpZmZlcmVuY2UgY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAic3Vydml2YWxfZGlmZiIpICU+JSAKICBzZXBhcmF0ZShgRGlmZmVyZW5jZSBjb250cmFzdGAsIGludG8gPSBjKCJHZW5lcmF0aW9uIiwgIkRpZmZlcmVuY2UgY29udHJhc3QiKSwgc2VwID0gIl8iKSAlPiUgCiAgbXV0YXRlKEdlbmVyYXRpb24gPSBhcy5udW1lcmljKHN0cl9yZW1vdmUoR2VuZXJhdGlvbiwgIkciKSkpCgoKIyBNYWtlIHRoZSB0aHJlZSBwbG90cwoKTGVhZl9wbG90X21jX0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX0IxICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYuYyIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJQdXJwIikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMC4xLCAwLjMpKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9cmV2KSArCiAgZ2VvbV92bGluZShsaW5ldHlwZSA9IDIsIHhpbnRlcmNlcHQgPSAwLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJNYWxlIC0gQ29udHJvbFxuUHJvcC4gc3VydiBsaW5lYWdlcyIsCiAgICAgICB5ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpIAoKTGVhZl9wbG90X21mX0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX0IxICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYuZiIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJUZWFsR3JuIikgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMC4xLCAwLjMpKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9cmV2KSArCiAgZ2VvbV92bGluZShsaW5ldHlwZSA9IDIsIHhpbnRlcmNlcHQgPSAwLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJNYWxlIC0gRmVtYWxlXG5Qcm9wLiBzdXJ2IGxpbmVhZ2VzIiwKICAgICAgIHkgPSBOVUxMKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKTGVhZl9wbG90X2ZjX0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX0IxICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYuZmMiKSAlPiUgCiAgZ2dwbG90KGFlcyhzdXJ2aXZhbF9kaWZmLCBhcy5mYWN0b3IoR2VuZXJhdGlvbikpKSArCiAgc3RhdF9pbnRlcnZhbCgud2lkdGggPSBjKDAuMDUsIDAuNjYsIDAuOTUpLCAKICAgICAgICAgICAgICAgIGhlaWdodCA9IDEsIHNob3cubGVnZW5kID0gRikgKwogIHJjYXJ0b2NvbG9yOjpzY2FsZV9jb2xvcl9jYXJ0b19kKHBhbGV0dGUgPSAiUGVhY2giKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjEsIDAuMykpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIkZlbWFsZSAtIENvbnRyb2xcblByb3AuIHN1cnYgbGluZWFnZXMiLAogICAgICAgeSA9IE5VTEwpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCgpgYGAKCkNvbWJpbmUgdGhlIDYgcGFuZWxzCgpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEwfQood2VpYnVsbF9zdXJ2X3Bsb3RfQjEgLyAoZXh0X3AxX0IxICsgZXh0X3AyX0IxKSkgLyAoTGVhZl9wbG90X21jX0IxICsgTGVhZl9wbG90X21mX0IxICsgTGVhZl9wbG90X2ZjX0IxKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAnYScpCmBgYAoKCioqRmlndXJlIDEqKi4gLi4uIAoKJH4kCgpUaGUgcGxvdCBkaXNwbGF5cyBhbiBpbnRlcmVzdGluZyBwYXR0ZXJuLCB3aGVyZSB0aGUgZXh0aW5jdGlvbiBjdXJ2ZXMgZm9yIGVhY2ggZXZvbHV0aW9uIHRyZWF0bWVudCBjb252ZXJnZSB1cG9uIG9uZSBhbm90aGVyIGluIHRoZSBsYXRlciBnZW5lcmF0aW9ucyBvZiB0aGUgZXhwZXJpbWVudC4gU2luZ2xlIHBhaXIsIGZ1bGwgc2libGluZyBpbmJyZWVkaW5nIGlzIGV4cGVjdGVkIHRvIHJlZHVjZSBnZW5vbWUtd2lkZSBoZXRlcm96eWdvc2l0eSB0byAwLjElIG9mIG9yaWdpbmFsIGxldmVscyBhZnRlciAxMCBnZW5lcmF0aW9ucyBpLmUuICQxMDAqXGZyYWN7MX17Mn1eezEwfSQgKGV4Y2VwdCBhdCBsb2NpIHdoZXJlIHNlbGVjdGlvbiBhZ2FpbnN0IGxldGhhbCByZWNlc3NpdmUgYWxsZWxlcyBhY3RpdmVseSBzdG9wcyBob21venlnb3NpdHkgZnJvbSBvY2N1cnJpbmcpLiBFdmVuIHZlcnkgc3Ryb25nIHNlbGVjdGlvbiBzaGFsbCByZWR1Y2UgdGhlIGVxdWlsaWJyaXVtIHBvaW50IGF0IHdoaWNoIG11dGF0aW9uLXNlbGVjdGlvbiBiYWxhbmNlIG9jY3VycyAoZXNwZWNpYWxseSBmb3IgcmVjZXNzaXZlIGFsbGVsZXMpIGFuZCBpdCBtYXkgYmUgdGhhdCBpbiBhIGZ1bGx5IGhvbW96eWdvdXMgc3RhdGUsIG11dGF0aW9uIGxvYWQgaXMgcmVsYXRpdmVseSBzaW1pbGFyIGFjcm9zcyBldm9sdXRpb24gdHJlYXRtZW50cy4gVGhlIHNoYXBlIHBhcmFtZXRlciBzdWdnZXN0cyB0aGF0IGxpbmVhZ2VzIGNhcnJ5aW5nIG1hbGUtbGltaXRlZCBhdXRvc29tZXMgc3VmZmVyIGZld2VyIGV4dGluY3Rpb24gZXZlbnRzIGR1cmluZyB0aGUgJ2FjdGl2ZScgaW5icmVlZGluZyBwaGFzZSB0aGFuIHRoZSBvdGhlciB0d28gdHJlYXRtZW50cywgdGhlbiBzdWZmZXIgYSBwcm9wb3J0aW9uYWxseSBzaW1pbGFyIGFtb3VudCBvbmNlIGluYnJlZWRpbmcgY2Vhc2VzIHRvIGluY3JlYXNlIGhvbW96eWdvc2l0eS4gVGhpcyBtYXkgYmUgYmVjYXVzZSBleHRpbmN0aW9uIGJlY29tZXMgbW9yZSBlbnZpcm9ubWVudGFsbHkgZHJpdmVuIG9yIGR1ZSB0byBuZXcgbXV0YXRpb25zICh0aGUgbGF0dGVyIGlzIHVubGlrZWx5KSBwYXN0IHRoaXMgcG9pbnQsIHByb2Nlc3NlcyB3aGljaCB3ZSBleHBlY3QgdG8gYWZmZWN0IGFsbCBsaW5lYWdlcyBpbiBhIHNpbWlsYXIgd2F5LiAKCiR+JAoKIyBQcm9kdWN0aXZpdHkgYW5hbHlzaXMKCiR+JAoKCldlIGhhdmUgc2V2ZXJhbCBoeXBvdGhlc2VzIHRoYXQgd2UgdGVzdCB3aXRoIHRoZSBwcm9kdWN0aXZpdHkgZGF0YS4gRmlyc3QsIHByb2R1Y3Rpdml0eSBzaG91bGQgYmUgbmVnYXRpdmVseSBjb3JyZWxhdGVkIHdpdGggdGhlIG51bWJlciBvZiBnZW5lcmF0aW9ucyBpbmJyZWVkaW5nIG9jY3VycywgZHVlIHRvIGluYnJlZWRpbmcgZGVwcmVzc2lvbi4gQXMgbWVudGlvbmVkIGFib3ZlLCB0aGlzIGVmZmVjdCBzaG91bGQgYmUgc3Ryb25nZXN0IGluIHRoZSBmaXJzdCB+OC0xMCBnZW5lcmF0aW9ucyBvZiB0aGUgZXhwZXJpbWVudCwgZHVyaW5nIHdoaWNoIGZ1bGwtc2libGluZyBpbmJyZWVkaW5nIHNob3VsZCBoYXZlIGFwcHJlY2lhYmxlIGVmZmVjdHMgb24gZ2Vub21lIHdpZGUgaGV0ZXJvenlnb3NpdHkuIEFmdGVyIHRoaXMgcG9pbnQsIHRoZSAlIG9mIGhldGVyb3p5Z29zaXR5IGFjcm9zcyB0aGUgZ2Vub21lIHNob3VsZCB2ZXJ5IHNtYWxsLiBIZW5jZSwgZWFjaCBsaW5lYWdlIGRvZXMgbm90IGdldCBtdWNoIG1vcmUgaW5icmVkIHBhc3QgdGhpcyBwb2ludCwgYW5kIHdlIGV4cGVjdCBwcm9kdWN0aXZpdHkgdG8gc3RhYmlsaXNlLCBhc3N1bWluZyB0aGUgbGluZWFnZSBpcyBzdGlsbCBleHRhbnQuIFNlY29uZCwgbGluZWFnZXMgY2FycnlpbmcgYXV0b3NvbWVzIHRoYXQgaGF2ZSByZXNwb25kZWQgdG8gc2VsZWN0aW9uIG9uIG1hbGVzIHNob3VsZCBleGhpYml0IGEgc21hbGxlciBkcm9wIGluIHByb2R1Y3Rpdml0eSBjb21wYXJlZCB3aXRoIGxpbmVhZ2VzIGNhcnlyaW5nIHRoZSBmZW1hbGUtYWRhcHRlZCBvciBjb250cm9sIGF1dG9zb21lcywgYmVjYXVzZSB0aGV5IGhhdmUgYSBoaXN0b3J5IG9mIHN0cm9uZ2VyIHNlbGVjdGlvbiB0aGF0IHNob3VsZCwgaW4gdGhlb3J5LCBoYXZlIHB1cmdlZCB0aGUgZ2Vub21lIG9mIHJlY2Vzc2l2ZSBkZWxldGVyaW91cyBhbGxlbGVzLgoKIyMgTG9hZCBpbiB0aGUgZGF0YQoKYGBge3J9CgpkYXRhIDwtCiAgcmVhZF9jc3YoIkRhdGEvUHJvZHVjdGl2aXR5X2RhdGEuY3N2IikKClByb2R1Y3Rpdml0eV9kYXRhIDwtIAogIGxlZnRfam9pbigKICAgIGRhdGEsCiAgICAKICAgIGRhdGEgJT4lIAogICAgICBkaXN0aW5jdChDcm9zcywgUmVwbGljYXRlKSAlPiUgCiAgICAgIHJvd2lkX3RvX2NvbHVtbigiTGluZWFnZSIpCiAgKSAlPiUgCiAgc2VsZWN0KExpbmVhZ2UsIGV2ZXJ5dGhpbmcoKSkgJT4lIAogIG11dGF0ZShhY3Jvc3MoMTo3LCBhcy5mYWN0b3IpLAogICAgICAgICBDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcgPSBGZW1hbGVfb2Zmc3ByaW5nICsgTWFsZV9vZmZzcHJpbmcsCiAgICAgICAgIFByZV93aW5kb3dfb2Zmc3ByaW5nID0gUHJlX3dpbmRvd19mZW1hbGVfb2Zmc3ByaW5nICsgUHJlX3dpbmRvd19tYWxlX29mZnNwcmluZywKICAgICAgICAgVG90YWxfZmVtYWxlX29mZnNwcmluZyA9IEZlbWFsZV9vZmZzcHJpbmcgKyBQcmVfd2luZG93X2ZlbWFsZV9vZmZzcHJpbmcsCiAgICAgICAgIFRvdGFsX21hbGVfb2Zmc3ByaW5nID0gTWFsZV9vZmZzcHJpbmcgKyBQcmVfd2luZG93X21hbGVfb2Zmc3ByaW5nLAogICAgICAgICBUb3RhbF9vZmZzcHJpbmcgPSBUb3RhbF9mZW1hbGVfb2Zmc3ByaW5nICsgVG90YWxfbWFsZV9vZmZzcHJpbmcpICU+JSAKICAjIEluIG9uZSBnZW5lcmF0aW9uIG9mIHRoZSBleHBlcmltZW50IChiMSA9IEcyNCAmIEIyID0gRzE1KSBzaWJsaW5nIHBhaXJzIHdlcmUgc2V0dXAgYSBkYXkgZWFybHkgYW5kIHJlbW92ZWQgZnJvbSB0aGVpciB2aWFscyBhdCB0aGUgcmVndWxhciB0aW1lLCBtZWFuaW5nIHRoYXQgdGhleSBoYWQgYW4gZXh0cmEgZGF5IHRvIHByb2R1Y2Ugb2Zmc3ByaW5nLiBUbyBjb3JyZWN0IGZvciB0aGlzIHdlIG11bHRpcGx5IG9mZnNwcmluZyBjb3VudHMgYnkgMC43NS4KICBtdXRhdGUoQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nID0gaWZfZWxzZShDb3VudF9jb25kaXRpb25zID09ICJFeHRyYSBkYXkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcgKiAwLjc1KSwgIENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZyksCiAgICAgICAgICMgbm90ZSB0aGF0IGJlY2F1c2UgZXZlcnl0aGluZyBpcyBtb3ZlZCBhIGRheSBlYXJseSwgcHJlLXdpbmRvdyBvZmZzcHJpbmcgY291bnRzIHdpbGwgc3RpbGwgYmUgaW5mbGF0ZWQgZXZlbiBhZnRlciB0aGlzIGNvcnJlY3Rpb24KICAgICAgICAgUHJlX3dpbmRvd19vZmZzcHJpbmcgPSBpZl9lbHNlKENvdW50X2NvbmRpdGlvbnMgPT0gIkV4dHJhIGRheSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKFByZV93aW5kb3dfb2Zmc3ByaW5nICogMC43NSksICBQcmVfd2luZG93X29mZnNwcmluZykpCiAgCiMgTWFrZSBhIHRpYmJsZSB0aGF0IG9ubHkgaW5jbHVkZXMgZGF0YSBmcm9tIHRoZSBmaXJzdCAyMCBnZW5lcmF0aW9ucyBvZiB0aGUgZXhwZXJpbWVudCAoQmxvY2sgMSByYW4gZm9yIDI5IGdlbnMsIHdoaWxlIEJsb2NrIDIgcmFuIGZvciAyMCkuIFRoZW4gcmVtb3ZlIGxpbmVhZ2UncyB0aGF0IGF0IHNvbWUgcG9pbnQgd2VyZSBsb3N0IGJlY2F1c2Ugb2YgaGFuZGxpbmcgZXJyb3JzIGFuZCB0aHVzIGRvIG5vdCBoYXZlIGRhdGEgZnJvbSB0aGF0IGdlbmVyYXRpb24gb253YXJkcy4KClByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuIDwtCiAgbGVmdF9qb2luKAogICAgUHJvZHVjdGl2aXR5X2RhdGEgJT4lIAogICAgICBmaWx0ZXIoR2VuZXJhdGlvbiA8IDIxKSAlPiUgCiAgICAgIGZpbHRlcihDb2xsZWN0aW9uX3dpbmRvd19vZmZzcHJpbmcgIT0gIk5BIikgJT4lICMgcmVtb3ZlIE5BIHZhbHVlcwogICAgICBncm91cF9ieShMaW5lYWdlLCBCbG9jaykgJT4lICMgdGhlc2UgcmVtYWluaW5nIGxpbmVzIHJlbW92ZSBsaW5lYWdlJ3MgdGhhdCBoYWQgYW4gTkEgdmFsdWUgCiAgICAgIGNvdW50KCkgJT4lIAogICAgICB1bmdyb3VwKCkgJT4lIAogICAgICBmaWx0ZXIobiA9PSAyMCksICMgcmVtb3ZlIGxpbmVhZ2UncyB0aGF0IGhhdmUgTkEgdmFsdWVzIGZvciBwcm9kdWN0aXZpdHkgaW4gYXQgbGVhc3Qgb25lIGdlbmVyYXRpb24KICAgIAogICAgUHJvZHVjdGl2aXR5X2RhdGEpICU+JSAKICBmaWx0ZXIoR2VuZXJhdGlvbiA8IDIxKSAjIG9ubHkgaW5jbHVkZSBkYXRhIGNvbGxlY3RlZCBvbiB0aGUgZmlyc3QgMjAgZ2VuZXJhdGlvbnMgb2YgaW5icmVlZGluZyAoYmxvY2sgMidzIGVuZHBvaW50KQoKIyBXZSBhbHNvIGluY2x1ZGUgYSBkYXRhZnJhbWUgdGhhdCByZW1vdmVzIGxpbmVhZ2VzIHRoYXQgYXJlIGV4dGluY3QuIFRoaXMgbWVhbnMgdGhhdCAwIHZhbHVlcyBhcmUgZmFyIGxlc3MgcHJldmFsZW50LiBXZSBjYW4gdXNlIHRoZSBgZXh0aW5jdGlvbl9kYXRhX3dyYW5nbGVkJEdlbnNfdG9fZXh0aW5jdGAgY29sdW1uIHRvIGhlbHAgdXMgaGVyZS4gCgpQcm9kdWN0aXZpdHlfZGF0YV90cmltbWVkX2V4dGFudCA8LQogIGxlZnRfam9pbigKICAgIFByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuLCAgCiAgICBleHRpbmN0aW9uX2RhdGFfd3JhbmdsZWQgJT4lIAogICAgICBzZWxlY3QoTGluZWFnZSwgR2Vuc190b19leHRpbmN0KQogICkgJT4lIAogIG11dGF0ZShFeHRpbmN0ID0gaWZfZWxzZShHZW5lcmF0aW9uID4gR2Vuc190b19leHRpbmN0LCAiWWVzIiwgIk5vIikpICU+JSAKICBmaWx0ZXIoRXh0aW5jdCA9PSAiTm8iKQpgYGAKCiMjIERvIHdlIG9ic2VydmUgaW5icmVlZGluZyBkZXByZXNzaW9uPwoKTGV0J3MgcGxvdCB0aGUgcmF3IGRhdGEgdG8gZ2V0IGFuIGlkZWEuCgpgYGB7cn0KCiMgQ29sbGVjdGlvbiB3aW5kb3cgcGxvdAoKcG9pbnRfcGxvdF8xIDwtCiAgUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW4gJT4lCiAgZ2dwbG90KGFlcyh4ID0gR2VuZXJhdGlvbiwgeSA9IENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZykpICsKICBnZW9tX2ppdHRlcihjb2xvdXIgPSBtZXQuYnJld2VyKCJPS2VlZmZlMiIpWzJdLCB3aWR0aCA9IDAuMjUsIAogICAgICAgICAgICAgIHNoYXBlID0gMS41LCBzdHJva2UgPTIsIHNpemUgPSAxLjIsIGFscGhhID0gMC4yNSkgKwogIGdlb21fc21vb3RoKHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbN10pICsKICBnZW9tX3Ntb290aChkYXRhID0gUHJvZHVjdGl2aXR5X2RhdGFfdHJpbW1lZF9leHRhbnQsIHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbNl0pICsKICB0aGVtZV90aWR5YmF5ZXMoKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDEsIDIwKSkgKwogIGxhYnMoeSA9ICJDb2xsZWN0aW9uIHdpbmRvd1xub2Zmc3ByaW5nIHByb2R1Y3Rpb24iLCB4ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpCgojIFRvdGFsIHByb2R1Y3Rpdml0eSBwbG90Cgpwb2ludF9wbG90XzIgPC0KICBQcm9kdWN0aXZpdHlfZGF0YSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gR2VuZXJhdGlvbiwgeSA9IFRvdGFsX29mZnNwcmluZykpICsKICBnZW9tX2ppdHRlcihjb2xvdXIgPSBtZXQuYnJld2VyKCJPS2VlZmZlMiIpWzJdLCB3aWR0aCA9IDAuMjUsIAogICAgICAgICAgICAgIHNoYXBlID0gMS41LCBzdHJva2UgPTIsIHNpemUgPSAxLjIsIGFscGhhID0gMC4yNSkgKwogIGdlb21fc21vb3RoKHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbN10pICsKICBnZW9tX3Ntb290aChkYXRhID0gUHJvZHVjdGl2aXR5X2RhdGFfdHJpbW1lZF9leHRhbnQsIHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbNl0pICsKICB0aGVtZV90aWR5YmF5ZXMoKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDEsIDIwKSkgKwogIGxhYnMoeSA9ICJUb3RhbCBvZmZzcHJpbmcgcHJvZHVjdGlvbiIsIHggPSAiR2VuZXJhdGlvbiBvZiBpbmJyZWVkaW5nIikgKwogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkKCnBvaW50X3Bsb3RfMSAvIHBvaW50X3Bsb3RfMgoKYGBgCgokfiQKCiMjIFRlc3RpbmcgZm9yIG91ciBjYXN1YWwgZWZmZWN0CgojIyMgTW9kZWxsaW5nIGFwcHJvYWNoCgpBcyBtZW50aW9uZWQgYWJvdmUsIHdlIGhhdmUgc3Ryb25nIGV4cGVjdGF0aW9ucyBmb3IgaG93IGZ1bGwtc2libGluZyBpbmJyZWVkaW5nIHNob3VsZCBhZmZlY3QgcHJvZHVjdGl2aXR5LiBBIGhhbHZpbmcgb2YgZ2Vub21lLXdpZGUgaGV0ZXJvenlnb3NpdHkgYW5kIHRoZSBleHByZXNzaW9uIG9mIHJlY2Vzc2l2ZSBkZWxldGVyaW91cyBhbGxlbGVzIHRoYXQgY29tZXMgd2l0aCB0aGlzIHNob3VsZCBmb2xsb3cgYSBwYXR0ZXJuIG9mIGV4cG9uZW50aWFsIGRlY2F5LiBUaGlzIG5vbi1saW5lYXIgcHJvY2VzcyBjYW4gYmUgbW9kZWxsZWQgdXNpbmcgdGhlIGBicm1zYCBub24tbGluZWFyIHN5bnRheC4gCgpIZXJlIHdlIG1vZGVsIHRoZSBwcm9kdWN0aXZpdHkgYXQgZ2VuZXJhdGlvbiAkdCQgdmlhIHRoZSBmdW5jdGlvbiAkYSAtIGVee1xsYW1iZGEgdH0kIHdoZXJlICRhJCBhbmQgJFxsYW1iZGEkIGFyZSBwYXJhbWV0ZXJzIHRoYXQgY29udHJvbCB0aGUgaW5pdGlhbCBwcm9kdWN0aXZpdHkgYW5kIHRoZSByYXRlIG9mIGl0cyBkZWNheSBhcyBnZW5lcmF0aW9ucyBvZiBpbmJyZWVkaW5nIHByb2dyZXNzLiBXZSBmb3JjZSAkYSQgdG8gYmUgcG9zaXRpdmUgdXNpbmcgdGhlIGBleHAoKWAgZnVuY3Rpb24sIHdoaWNoIGV4cHJlc3NlcyBpdCBvbiB0aGUgZXhwb25lbnRpYWwgc2NhbGUuIExhcmdlICRhJCBpbmRpY2F0ZXMgaGlnaGVyIHN0YXJ0aW5nIHByb2R1Y3Rpdml0eSBhdCBnZW5lcmF0aW9uIDAgKHdlIHN0YXJ0ZWQgb2JzZXJ2YXRpb24gYXQgZ2VuZXJhdGlvbiAxLCB0aGUgcHJvZHVjdGl2aXR5IGZvciB3aGljaCBpcyBnaXZlbiBieSAkYSAtIGVee1xsYW1iZGF9JCkuIFBvc2l0aXZlIHZhbHVlcyBvZiAkXGxhbWJkYSQgaW5kaWNhdGUgdGhhdCBwcm9kdWN0aXZpdHkgZGVjbGluZXMgd2l0aCBpbmJyZWVkaW5nLCB3aGljaCBpcyBvdXIgc3Ryb25nIGV4cGVjdGF0aW9uIGFuZCBjbGVhcmx5IHRoZSBjYXNlIGZvbGxvd2luZyBpbnNwZWN0aW9uIG9mIHRoZSByYXcgZGF0YSAoc2VlIEZpZ3VyZSBTWCkuIAoKV2UgbW9kZWwgaW5icmVlZGluZyBkZXByZXNzaW9uIHdoaWxlIGluY2x1ZGluZyB6ZXJvIHZhbHVlcyBmb3IgYWxsIHJvd3Mgd2hlcmUgYSBsaW5lYWdlIHdhcyBleHRpbmN0LiBUaGlzIGhlbHBzIGNvbWJhdCB1bmRlcmVzdGltYXRpb24gb2YgdGhlIGRlY2F5IHBhcmFtZXRlciwgY2F1c2VkIGJ5IHRoZSBub24tcmFuZG9tIGV4dGluY3Rpb24gb2YgbGluZWFnZXMsIHdoZXJlIGhpZ2ggZml0bmVzcyBsaW5lYWdlcyBiZWNvbWUgb3Zlci1yZXByZXNlbnRlZCBhcyB0aGUgZ2VuZXJhdGlvbnMgb2YgaW5icmVlZGluZyBwcm9ncmVzcyAoaS5lLiBzZWxlY3Rpb24pLiAKCioqRml4ZWQgYW5kIHJhbmRvbSBlZmZlY3RzKioKCkluIHRoZSBgYnJtc2Agbm9uLWxpbmVhciBzeW50YXgsIGRpZmZlcmVudCBmb3JtdWxhcyBjYW4gYmUgZml0IGZvciBlYWNoIHBhcmFtZXRlci4gV2UgZml0IHRoZSBzYW1lIGZpeGVkIGVmZmVjdHMgZm9yICRhJCBhbmQgJFxsYW1iZGEkOiBgRXZvbHV0aW9uIHRyZWF0bWVudGAgYW5kICBgQmxvY2tgLiBXZSBmaXQgJ0xpbmVhZ2UnIGFzIGEgcmFuZG9tIGVmZmVjdCB0byBhY2NvdW50IGZvciByZXBlYXRlZCBtZWFzdXJlbWVudHMgdGFrZW4gb24gZWFjaCBsaW5lYWdlIGZvciAkYSQsIGJ1dCBhcmUgdW5hYmxlIHRvIGRvIHRoaXMgZm9yICRcbGFtYmRhJCwgYXMgaW5kaXZpZHVhbCBsaW5lYWdlIHByb2R1Y3Rpdml0eSBjdXJ2ZXMgYXJlIGhpZ2hseSBoZXRlcm9za2VkYXN0aWMsIGFuZCBhcmUgc2tld2VkIGJ5IGV4dGluY3Rpb24gZXZlbnRzLiBUbyBtaW5pbWlzZSBwc2V1ZG9yZXBsaWNhdGlvbiBmb3IgJFxsYW1iZGEkLCB3ZSBmaXQgYENyb3NzYCBhcyBhIHJhbmRvbSBlZmZlY3QgKGN1cnJlbnRseSBvbmx5IG9uICRcbGFtYmRhJCksIGFzIHdlIGRvIGZvciB0aGUgZXh0aW5jdGlvbiBkYXRhLgoKJH4kCgojIyMgU2ltdWxhdGUgdGhlIGN1cnZlLCB3aXRoIHRoZSBwcmlvcnMgd2Ugd2lsbCBzcGVjaWZ5CgpgYGB7cn0KCm4gPC0gMWU0CgojIGRlZmluZSB0aGUgeC1heGlzIGJyZWFrcwphdCA8LSAxOjIwCgojIGhvdyBtYW55IHByaW9yIGRyYXdzIHdvdWxkIHlvdSBsaWtlPwpuX2RyYXdzIDwtIDIwMAoKIyBzaW11bGF0ZQpzZXQuc2VlZCgxNikKCnByaW9yIDwtCiAgdGliYmxlKGluZGV4ID0gMTpuLAogICAgICAgICBhICAgPSBybm9ybShuLCBtZWFuID0gNC41LCBzZCA9IDAuNSksCiAgICAgICAgIGxhbWJkYSAgICAgPSBybm9ybShuLCBtZWFuID0gMC4yLCBzZCA9IDAuMSkpICU+JSAKICBzbGljZV9zYW1wbGUobiA9IG5fZHJhd3MpICU+JSAKICBleHBhbmQobmVzdGluZyhpbmRleCwgYSwgbGFtYmRhKSwKICAgICAgICAgR2VuZXJhdGlvbiA9IHNlcShmcm9tID0gMCwgdG8gPSAyMCwgbGVuZ3RoLm91dCA9IDFlMikpICU+JSAKICBtdXRhdGUocHJvZHVjdGl2aXR5ID0gZXhwKGEgLSBsYW1iZGEgKiBHZW5lcmF0aW9uKSkgCgoKcHJpb3IgJT4lIAogIGdncGxvdChhZXMoeCA9IEdlbmVyYXRpb24sIHkgPSBwcm9kdWN0aXZpdHksIGdyb3VwID0gaW5kZXgpKSArCiAgZ2VvbV9saW5lKHNpemUgPSAxLzIsIGFscGhhID0gMS80LCBjb2xvdXIgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiKVsyXSkgKwogIHRoZW1lX3RpZHliYXllcygpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDMwMCksIGV4cGFuZCA9IGV4cGFuc2lvbihtdWx0ID0gYygwLCAuMSkpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwyMCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBsYWJzKHkgPSAiTGluZWFnZSBwcm9kdWN0aXZpdHkiLCB4ID0gIkdlbmVyYXRpb24gb2YgaW5icmVlZGluZyIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpCgpgYGAKCioqRmlndXJlIFhYKio6IFByaW9yIHByZWRpY3RpdmUgc2ltdWxhdGlvbiBmb3IgdGhlIHByb2R1Y3Rpdml0eSBkZWNsaW5lIG1vZGVsLiBUaGUgcGxvdCBzaG93cyB0aGUgcmVzdWx0cyBmcm9tIDEwMCBwcmlvciBkcmF3cy4KCiMjIyBGaXQgdGhlIG5vbi1saW5lYXIgbW9kZWwKCmBgYHtyfQoKbm9ubGluZWFyX3Byb2R1Y3Rpdml0eSA8LSAKICBicm0oYmYoQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nIH4gZXhwKGEgLSAobGFtYmRhICogR2VuZXJhdGlvbikpLAogICAgICAgICBhIH4gMCArIFRyZWF0bWVudCAqIEJsb2NrICsgKDF8TGluZWFnZSksIAogICAgICAgICBsYW1iZGEgfiAwICsgVHJlYXRtZW50ICogQmxvY2sgKyAoMXxDcm9zcyksIAogICAgICAgICBubCA9IFRSVUUpLAogICAgICBkYXRhID0gUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW4sCiAgICAgIGZhbWlseSA9IG5lZ2Jpbm9taWFsKGxpbmsgPSAiaWRlbnRpdHkiKSwKICAgICAgcHJpb3IgPSBjKHByaW9yKG5vcm1hbCg0LjUsIDAuNSksIGNsYXNzID0gYiwgY29lZiA9IFRyZWF0bWVudENvbnRyb2wsIG5scGFyID0gImEiKSwKICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCg0LjUsIDAuNSksIGNsYXNzID0gYiwgY29lZiA9IFRyZWF0bWVudEZlbWFsZSwgbmxwYXIgPSAiYSIpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDQuNSwgMC41KSwgY2xhc3MgPSBiLCBjb2VmID0gVHJlYXRtZW50TWFsZSwgbmxwYXIgPSAiYSIpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAsIDAuNSksIGNsYXNzID0gYiwgY29lZiA9IEJsb2NrMiwgbmxwYXIgPSAiYSIpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAuMiwgMC4xKSwgY2xhc3MgPSBiLCBjb2VmID0gVHJlYXRtZW50Q29udHJvbCwgbmxwYXIgPSAibGFtYmRhIiksCiAgICAgICAgICAgICAgICBwcmlvcihub3JtYWwoMC4yLCAwLjEpLCBjbGFzcyA9IGIsIGNvZWYgPSBUcmVhdG1lbnRGZW1hbGUsIG5scGFyID0gImxhbWJkYSIpLAogICAgICAgICAgICAgICAgcHJpb3Iobm9ybWFsKDAuMiwgMC4xKSwgY2xhc3MgPSBiLCBjb2VmID0gVHJlYXRtZW50TWFsZSwgbmxwYXIgPSAibGFtYmRhIiksCiAgICAgICAgICAgICAgICBwcmlvcihub3JtYWwoMCwgMC4xKSwgY2xhc3MgPSBiLCBjb2VmID0gQmxvY2syLCBubHBhciA9ICJsYW1iZGEiKSwKICAgICAgICAgICAgICAgIHByaW9yKGdhbW1hKDMsIDEuNSksIGNsYXNzID0gc2QsIG5scGFyID0gImEiKSwKICAgICAgICAgICAgICAgIHByaW9yKGdhbW1hKDAuMSwgMiksIGNsYXNzID0gc2QsIG5scGFyID0gImxhbWJkYSIpKSwKICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjgsIG1heF90cmVlZGVwdGggPSAxNSksIHNlZWQgPSAxLAogICAgICBpdGVyID0gMzAwMDAsIHdhcm11cCA9IDUwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwKICAgICAgZmlsZSA9ICJGaXRzL25vbl9saW5lYXJfcHJvZHVjdGl2aXR5X21vZGVsXzIiKQoKCmBgYAoKIyMjIEhvdyBkb2VzIG91ciBjdXJ2ZSBmaXQgdGhlIGRhdGEKCmBgYHtyfQoKCm5ld19kYXRhIDwtIAogIFByb2R1Y3Rpdml0eV9kYXRhX2NsZWFuICU+JSAKICBzZWxlY3QoR2VuZXJhdGlvbiwgVHJlYXRtZW50LCBCbG9jaykgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBtdXRhdGUoa2V5ID0gcGFzdGUoIlYiLCAxOm4oKSwgc2VwID0gIiIpKQoKcHJlZHMgPC0gYXMuZGF0YS5mcmFtZShmaXR0ZWQobm9ubGluZWFyX3Byb2R1Y3Rpdml0eSwgbmV3ZGF0YSA9IG5ld19kYXRhLCByZV9mb3JtdWxhID0gTkEsIHN1bW1hcnk9RikpICU+JSAKICBtdXRhdGUoZHJhdyA9IDE6bigpKSAlPiUgCiAgZ2F0aGVyKGtleSwgQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nLCAtZHJhdykgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBsZWZ0X2pvaW4obmV3X2RhdGEsIGJ5ID0gImtleSIpICU+JSAKICBzZWxlY3QoLWtleSkgJT4lIAogICAgbXV0YXRlKFRyZWF0bWVudCA9IGNhc2Vfd2hlbigKICAgIFRyZWF0bWVudCA9PSAiRmVtYWxlIiB+ICJGZW1hbGUtbGltaXRlZCIsCiAgICBUcmVhdG1lbnQgPT0gIk1hbGUiIH4gIk1hbGUtbGltaXRlZCIsCiAgICBUcmVhdG1lbnQgPT0gIkNvbnRyb2wiIH4gIkNvbnRyb2wiKSkKCnByZWRzX3N1bW1hcnkgPC0KICBwcmVkcyAlPiUgCiAgZ3JvdXBfYnkoVHJlYXRtZW50LCBHZW5lcmF0aW9uLCBCbG9jaykgJT4lCiAgbWVkaWFuX3FpKENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZywgLndpZHRoID0gMC41KQoKbmxfcDEgPC0KICBQcm9kdWN0aXZpdHlfZGF0YV9jbGVhbiAlPiUgCiAgZmlsdGVyKEJsb2NrID09IDEpICU+JSAgCiAgZ2dwbG90KGFlcyh4ID0gR2VuZXJhdGlvbiwgeSA9IENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZykpICsKICBnZW9tX2ppdHRlcihjb2xvdXIgPSBtZXQuYnJld2VyKCJPS2VlZmZlMiIpWzJdLCB3aWR0aCA9IDAuMjUsIAogICAgICAgICAgICAgIHNoYXBlID0gMS41LCBzdHJva2UgPTIsIHNpemUgPSAxLjIsIGFscGhhID0gMC4yKSArCiAjIGdlb21fc21vb3RoKHNpemUgPSAxLjUsIGNvbG91ciA9IG1ldC5icmV3ZXIoIk9LZWVmZmUyIilbN10sIGFscGhhID0gMC40KSArCiAgZ2VvbV9yaWJib24oZGF0YSA9IHByZWRzX3N1bW1hcnkgJT4lIGZpbHRlcihCbG9jayA9PSAiMSIpLCAKICAgICAgICAgICAgIGFlcyh5bWluID0gLmxvd2VyLCB5bWF4ID0gLnVwcGVyLCBmaWxsID0gVHJlYXRtZW50KSwgYWxwaGEgPSAxLzIpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gVHJlYXRtZW50LCBjb2xvdXIgPSBUcmVhdG1lbnQpLCBkYXRhID0gcHJlZHNfc3VtbWFyeSAlPiUgZmlsdGVyKEJsb2NrID09IDEpLAogICAgICAgICAgICBzaXplID0gMSwgYWxwaGEgPSAxLCBsaW5ldHlwZSA9IDUpICsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzID0gYygxLCAyLCAzKSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMyksIGd1aWRlID0gIm5vbmUiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMykpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAuMDEsIDApKSkgKwogIHRoZW1lX3RpZHliYXllcygpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMSwgMjApLCB5bGltID0gYygwLCAxNTApKSArCiAgbGFicyh5ID0gIkxpbmVhZ2UgcHJvZHVjdGl2aXR5IiwgeCA9ICJHZW5lcmF0aW9uIG9mIGluYnJlZWRpbmciLCBmaWxsID0gIlNlbGVjdGlvbiByZXNwb25zZVxuaGlzdG9yeSIpICsKICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKC45OSwgLjk5KSwKICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoInJpZ2h0IiwgInRvcCIpLAogICAgICAgIGxlZ2VuZC5ib3guanVzdCA9ICJyaWdodCIsCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbig2LCA2LCA2LCA2KSkKCm5sX3AyIDwtCiAgUHJvZHVjdGl2aXR5X2RhdGFfY2xlYW4gJT4lIGZpbHRlcihCbG9jayA9PSAyKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gR2VuZXJhdGlvbiwgeSA9IENvbGxlY3Rpb25fd2luZG93X29mZnNwcmluZykpICsKICBnZW9tX2ppdHRlcihjb2xvdXIgPSBtZXQuYnJld2VyKCJPS2VlZmZlMiIpWzJdLCB3aWR0aCA9IDAuMjUsIAogICAgICAgICAgICAgIHNoYXBlID0gMS41LCBzdHJva2UgPTIsIHNpemUgPSAxLjIsIGFscGhhID0gMC4yKSArCiAgIyBnZW9tX3Ntb290aChzaXplID0gMS41LCBjb2xvdXIgPSBtZXQuYnJld2VyKCJPS2VlZmZlMiIpWzddLCBhbHBoYSA9IDAuNCkgKwogIGdlb21fcmliYm9uKGRhdGEgPSBwcmVkc19zdW1tYXJ5ICU+JSBmaWx0ZXIoQmxvY2sgPT0gMiksIAogICAgICAgICAgICAgIGFlcyh5bWluID0gLmxvd2VyLCB5bWF4ID0gLnVwcGVyLCBmaWxsID0gVHJlYXRtZW50KSwgYWxwaGEgPSAxLzIpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gVHJlYXRtZW50LCBjb2xvdXIgPSBUcmVhdG1lbnQpLCBkYXRhID0gcHJlZHNfc3VtbWFyeSAlPiUgZmlsdGVyKEJsb2NrID09IDIpLAogICAgICAgICAgICBzaXplID0gMSwgYWxwaGEgPSAxLCBsaW5ldHlwZSA9IDUpICsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzID0gYygxLCAyLCAzKSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMyksIGd1aWRlID0gIm5vbmUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGV4cGFuc2lvbihtdWx0ID0gYygwLjAxLCAwKSkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAzKSkgKwogIHRoZW1lX3RpZHliYXllcygpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMSwgMjApLCB5bGltID0gYygwLCAxNTApKSArCiAgbGFicyh5ID0gIkxpbmVhZ2UgcHJvZHVjdGl2aXR5IiwgeCA9ICJHZW5lcmF0aW9uIG9mIGluYnJlZWRpbmciLCBzdWJ0aXRsZSA9ICJCbG9jayAyIiwgZmlsbCA9ICJTZWxlY3Rpb24gcmVzcG9uc2Vcbmhpc3RvcnkiKSArCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYyguOTksIC45OSksCiAgICAgICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKCJyaWdodCIsICJ0b3AiKSwKICAgICAgICBsZWdlbmQuYm94Lmp1c3QgPSAicmlnaHQiLAogICAgICAgIGxlZ2VuZC5tYXJnaW4gPSBtYXJnaW4oNiwgNiwgNiwgNikpCgpgYGAKCiR+JAoKRXN0aW1hdGluZyAkYSQgYW5kICRcbGFtYmRhJCAKCmBgYHtyfQoKSW5pdGlhbF9wcm9kdWN0aXZpdHlfZXN0aW1hdGVzIDwtCmFzX2RyYXdzX2RmKG5vbmxpbmVhcl9wcm9kdWN0aXZpdHksIHZhcmlhYmxlID0gIl5iX2EiLCByZWdleCA9IFRSVUUpICU+JSAKICBtdXRhdGUoYEZlbWFsZS1saW1pdGVkIEIxYCA9IGJfYV9UcmVhdG1lbnRGZW1hbGUsCiAgICAgICAgIGBNYWxlLWxpbWl0ZWQgQjFgID0gYl9hX1RyZWF0bWVudE1hbGUsCiAgICAgICAgIGBDb250cm9sIEIxYCA9IGJfYV9UcmVhdG1lbnRDb250cm9sLAogICAgICAgICBgRmVtYWxlLWxpbWl0ZWQgQjJgID0gYl9hX1RyZWF0bWVudEZlbWFsZSArIGJfYV9CbG9jazIgKyBgYl9hX1RyZWF0bWVudEZlbWFsZTpCbG9jazJgLAogICAgICAgICBgTWFsZS1saW1pdGVkIEIyYCA9IGJfYV9UcmVhdG1lbnRNYWxlICsgYl9hX0Jsb2NrMiArIGBiX2FfVHJlYXRtZW50TWFsZTpCbG9jazJgLAogICAgICAgICBgQ29udHJvbCBCMmAgPSBiX2FfVHJlYXRtZW50Q29udHJvbCArIGJfYV9CbG9jazIpICU+JQogIHNlbGVjdChgRmVtYWxlLWxpbWl0ZWQgQjFgLCBgTWFsZS1saW1pdGVkIEIxYCwgYENvbnRyb2wgQjFgLAogICAgICAgICBgRmVtYWxlLWxpbWl0ZWQgQjJgLCBgTWFsZS1saW1pdGVkIEIyYCwgYENvbnRyb2wgQjJgKSAlPiUgCiAgbXV0YXRlX2FsbCh+IGV4cCgueCkpICU+JSAKICBtdXRhdGUocG9zdGVyaW9yX3NhbXBsZSA9IDE6bigpKSAlPiUgCiAgZ2F0aGVyKEV2b2x1dGlvbl90cmVhdG1lbnQsIGEsIC1wb3N0ZXJpb3Jfc2FtcGxlKSAlPiUgCiAgc2VwYXJhdGUoY29sID0gRXZvbHV0aW9uX3RyZWF0bWVudCwgc2VwID0gIiAiLCBpbnRvID0gYygiRXZvbHV0aW9uX3RyZWF0bWVudCIsICJCbG9jayIpKQogIAoKSW5pdGlhbF9wcm9kdWN0aXZpdHlfcGxvdF9CMSA8LQogIEluaXRpYWxfcHJvZHVjdGl2aXR5X2VzdGltYXRlcyAlPiUgCiAgZmlsdGVyKEJsb2NrID09ICJCMSIpICU+JQogIAogIGdncGxvdChhZXMoeCA9IGEsIHkgPSBFdm9sdXRpb25fdHJlYXRtZW50KSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IEV2b2x1dGlvbl90cmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwKICAgICAgICAgICAgICAgc2xhYl9jb2xvdXIgPSAiYmxhY2siLCBzbGFiX3NpemUgPSAwLjgpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgNSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoNTAsIDE1MCkpICsKICBsYWJzKHg9ZXhwcmVzc2lvbihwYXN0ZSgiSW5pdGlhbCBwcm9kdWN0aXZpdHkgcGFyYW1ldGVyICIsaXRhbGljKCJhIikpKSwgeSA9ICJTZWxlY3Rpb24gcmVzcG9uc2UgaGlzdG9yeSIpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcpLCAjdHJhbnNwYXJlbnQgcGFuZWwgYmcKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnLCBjb2xvcj1OQSksICN0cmFuc3BhcmVudCBwbG90IGJnCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgI3RyYW5zcGFyZW50IGxlZ2VuZCBwYW5lbAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCgoKSW5pdGlhbF9wcm9kdWN0aXZpdHlfcGxvdF9CMiA8LQogIEluaXRpYWxfcHJvZHVjdGl2aXR5X2VzdGltYXRlcyAlPiUgCiAgZmlsdGVyKEJsb2NrID09ICJCMiIpICU+JQogIAogIGdncGxvdChhZXMoeCA9IGEsIHkgPSBFdm9sdXRpb25fdHJlYXRtZW50KSkgKwogIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IEV2b2x1dGlvbl90cmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwKICAgICAgICAgICAgICAgc2xhYl9jb2xvdXIgPSAiYmxhY2siLCBzbGFiX3NpemUgPSAwLjgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KSkgKwogIGxhYnMoeD1leHByZXNzaW9uKHBhc3RlKCJJbml0aWFsIHByb2R1Y3Rpdml0eSBwYXJhbWV0ZXIgIixpdGFsaWMoImEiKSkpLCB5ID0gIlNlbGVjdGlvbiByZXNwb25zZSBoaXN0b3J5IikgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBwYW5lbCBiZwogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcsIGNvbG9yPU5BKSwgI3RyYW5zcGFyZW50IHBsb3QgYmcKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAjdHJhbnNwYXJlbnQgbGVnZW5kIHBhbmVsCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSkKCgpkZWNheV9lc3RpbWF0ZXMgPC0gIAogIGFzX2RyYXdzX2RmKG5vbmxpbmVhcl9wcm9kdWN0aXZpdHksIHZhcmlhYmxlID0gIl5iX2xhbWJkYSIsIHJlZ2V4ID0gVFJVRSkgJT4lIAogIG11dGF0ZShgRmVtYWxlLWxpbWl0ZWQgQjFgID0gYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlLAogICAgICAgICBgTWFsZS1saW1pdGVkIEIxYCA9IGJfbGFtYmRhX1RyZWF0bWVudE1hbGUsCiAgICAgICAgIGBDb250cm9sIEIxYCA9IGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wsCiAgICAgICAgIGBGZW1hbGUtbGltaXRlZCBCMmAgPSBiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUgKyBiX2xhbWJkYV9CbG9jazIgKyBgYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlOkJsb2NrMmAsCiAgICAgICAgIGBNYWxlLWxpbWl0ZWQgQjJgID0gYl9sYW1iZGFfVHJlYXRtZW50TWFsZSArIGJfbGFtYmRhX0Jsb2NrMiArIGBiX2xhbWJkYV9UcmVhdG1lbnRNYWxlOkJsb2NrMmAsCiAgICAgICAgIGBDb250cm9sIEIyYCA9IGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wgKyBiX2xhbWJkYV9CbG9jazIpICU+JQogc2VsZWN0KGBGZW1hbGUtbGltaXRlZCBCMWAsIGBNYWxlLWxpbWl0ZWQgQjFgLCBgQ29udHJvbCBCMWAsCiAgICAgICAgIGBGZW1hbGUtbGltaXRlZCBCMmAsIGBNYWxlLWxpbWl0ZWQgQjJgLCBgQ29udHJvbCBCMmApICU+JSAKICBtdXRhdGUocG9zdGVyaW9yX3NhbXBsZSA9IDE6bigpKSAlPiUgCiAgZ2F0aGVyKEV2b2x1dGlvbl90cmVhdG1lbnQsIGxhbWJkYSwgLXBvc3Rlcmlvcl9zYW1wbGUpICU+JQogIHNlcGFyYXRlKGNvbCA9IEV2b2x1dGlvbl90cmVhdG1lbnQsIHNlcCA9ICIgIiwgaW50byA9IGMoIkV2b2x1dGlvbl90cmVhdG1lbnQiLCAiQmxvY2siKSkKICAKCmRlY2F5X3Bsb3RfQjEgPC0KICBkZWNheV9lc3RpbWF0ZXMgJT4lIAogIGZpbHRlcihCbG9jayA9PSAiQjEiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbGFtYmRhLCB5ID0gRXZvbHV0aW9uX3RyZWF0bWVudCkpICsKICAgIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IEV2b2x1dGlvbl90cmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwgCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUsCiAgICAgICAgICAgICAgIHNsYWJfY29sb3VyID0gImJsYWNrIiwgc2xhYl9zaXplID0gMC44KSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgNSkpICsKICBsYWJzKHg9ZXhwcmVzc2lvbihwYXN0ZSgiRGVjYXkgcmF0ZSBwYXJhbWV0ZXIgIiwgbGFtYmRhLCkpLCB5ID0gIlNlbGVjdGlvbiByZXNwb25zZSBoaXN0b3J5IikgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JyksICN0cmFuc3BhcmVudCBwYW5lbCBiZwogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSd0cmFuc3BhcmVudCcsIGNvbG9yPU5BKSwgI3RyYW5zcGFyZW50IHBsb3QgYmcKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAjdHJhbnNwYXJlbnQgbGVnZW5kIHBhbmVsCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSkKCmRlY2F5X3Bsb3RfQjIgPC0KICBkZWNheV9lc3RpbWF0ZXMgJT4lIAogIGZpbHRlcihCbG9jayA9PSAiQjIiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbGFtYmRhLCB5ID0gRXZvbHV0aW9uX3RyZWF0bWVudCkpICsKICAgIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IEV2b2x1dGlvbl90cmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDEsCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwKICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwKICAgICAgICAgICAgICAgc2xhYl9jb2xvdXIgPSAiYmxhY2siLCBzbGFiX3NpemUgPSAwLjgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KSkgKwogIGxhYnMoeD1leHByZXNzaW9uKHBhc3RlKCJEZWNheSByYXRlIHBhcmFtZXRlciAiLCBsYW1iZGEsKSksIHkgPSAiU2VsZWN0aW9uIHJlc3BvbnNlIGhpc3RvcnkiKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ndHJhbnNwYXJlbnQnKSwgI3RyYW5zcGFyZW50IHBhbmVsIGJnCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9J3RyYW5zcGFyZW50JywgY29sb3I9TkEpLCAjdHJhbnNwYXJlbnQgcGxvdCBiZwogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsICN0cmFuc3BhcmVudCBsZWdlbmQgcGFuZWwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKYGBgCgpDcmVhdGUgbGVhZiBwbG90cyBsaWtlIHRob3NlIGluIEZpZ3VyZSAxCgpgYGB7cn0KcHJvZHVjdGl2aXR5X2N1cnZlIDwtCiAgbm9ubGluZWFyX3Byb2R1Y3Rpdml0eSAlPiUgCiAgYXNfZHJhd3NfZGYoKSAlPiUgCiAgc2VsZWN0KGNvbnRhaW5zKCJiXyIpKSAlPiUgCiAgbXV0YXRlKGFjcm9zcygxOjMsIH4gZXhwKC54KSksCiAgICAgICAgIENvbnRyb2xfMCAgPSBiX2FfVHJlYXRtZW50Q29udHJvbCAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wpKjApLAogICAgICAgICBDb250cm9sXzEgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSoxKSwKICAgICAgICAgQ29udHJvbF8yICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMiksCiAgICAgICAgIENvbnRyb2xfMyAgPSBiX2FfVHJlYXRtZW50Q29udHJvbCAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wpKjMpLAogICAgICAgICBDb250cm9sXzQgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSo0KSwKICAgICAgICAgQ29udHJvbF81ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqNSksCiAgICAgICAgIENvbnRyb2xfNiAgPSBiX2FfVHJlYXRtZW50Q29udHJvbCAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wpKjYpLAogICAgICAgICBDb250cm9sXzcgID0gYl9hX1RyZWF0bWVudENvbnRyb2wgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRDb250cm9sKSo3KSwKICAgICAgICAgQ29udHJvbF84ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqOCksCiAgICAgICAgIENvbnRyb2xfOSAgPSBiX2FfVHJlYXRtZW50Q29udHJvbCAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudENvbnRyb2wpKjkpLAogICAgICAgICBDb250cm9sXzEwICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTApLAogICAgICAgICBDb250cm9sXzExICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTEpLAogICAgICAgICBDb250cm9sXzEyICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTIpLAogICAgICAgICBDb250cm9sXzEzICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTMpLAogICAgICAgICBDb250cm9sXzE0ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTQpLAogICAgICAgICBDb250cm9sXzE1ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTUpLAogICAgICAgICBDb250cm9sXzE2ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTYpLAogICAgICAgICBDb250cm9sXzE3ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTcpLAogICAgICAgICBDb250cm9sXzE4ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTgpLAogICAgICAgICBDb250cm9sXzE5ICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMTkpLAogICAgICAgICBDb250cm9sXzIwICA9IGJfYV9UcmVhdG1lbnRDb250cm9sICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50Q29udHJvbCkqMjApLAogICAgICAgICBGZW1hbGVfMCAgPSBiX2FfVHJlYXRtZW50RmVtYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlKSowKSwKICAgICAgICAgRmVtYWxlXzEgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqMSksCiAgICAgICAgIEZlbWFsZV8yICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjIpLAogICAgICAgICBGZW1hbGVfMyAgPSBiX2FfVHJlYXRtZW50RmVtYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlKSozKSwKICAgICAgICAgRmVtYWxlXzQgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqNCksCiAgICAgICAgIEZlbWFsZV81ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjUpLAogICAgICAgICBGZW1hbGVfNiAgPSBiX2FfVHJlYXRtZW50RmVtYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlKSo2KSwKICAgICAgICAgRmVtYWxlXzcgID0gYl9hX1RyZWF0bWVudEZlbWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudEZlbWFsZSkqNyksCiAgICAgICAgIEZlbWFsZV84ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjgpLAogICAgICAgICBGZW1hbGVfOSAgPSBiX2FfVHJlYXRtZW50RmVtYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50RmVtYWxlKSo5KSwKICAgICAgICAgRmVtYWxlXzEwICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjEwKSwKICAgICAgICAgRmVtYWxlXzExICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjExKSwKICAgICAgICAgRmVtYWxlXzEyICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjEyKSwKICAgICAgICAgRmVtYWxlXzEzICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjEzKSwKICAgICAgICAgRmVtYWxlXzE0ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjE0KSwKICAgICAgICAgRmVtYWxlXzE1ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjE1KSwKICAgICAgICAgRmVtYWxlXzE2ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjE2KSwKICAgICAgICAgRmVtYWxlXzE3ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjE3KSwKICAgICAgICAgRmVtYWxlXzE4ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjE4KSwKICAgICAgICAgRmVtYWxlXzE5ICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjE5KSwKICAgICAgICAgRmVtYWxlXzIwICA9IGJfYV9UcmVhdG1lbnRGZW1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRGZW1hbGUpKjIwKSwKICAgICAgICAgTWFsZV8wICA9IGJfYV9UcmVhdG1lbnRNYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50TWFsZSkqMCksCiAgICAgICAgIE1hbGVfMSAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjEpLAogICAgICAgICBNYWxlXzIgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoyKSwKICAgICAgICAgTWFsZV8zICA9IGJfYV9UcmVhdG1lbnRNYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50TWFsZSkqMyksCiAgICAgICAgIE1hbGVfNCAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjQpLAogICAgICAgICBNYWxlXzUgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSo1KSwKICAgICAgICAgTWFsZV82ICA9IGJfYV9UcmVhdG1lbnRNYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50TWFsZSkqNiksCiAgICAgICAgIE1hbGVfNyAgPSBiX2FfVHJlYXRtZW50TWFsZSAqIGV4cCgtKGJfbGFtYmRhX1RyZWF0bWVudE1hbGUpKjcpLAogICAgICAgICBNYWxlXzggID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSo4KSwKICAgICAgICAgTWFsZV85ICA9IGJfYV9UcmVhdG1lbnRNYWxlICogZXhwKC0oYl9sYW1iZGFfVHJlYXRtZW50TWFsZSkqOSksCiAgICAgICAgIE1hbGVfMTAgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxMCksCiAgICAgICAgIE1hbGVfMTEgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxMSksCiAgICAgICAgIE1hbGVfMTIgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxMiksCiAgICAgICAgIE1hbGVfMTMgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxMyksCiAgICAgICAgIE1hbGVfMTQgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxNCksCiAgICAgICAgIE1hbGVfMTUgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxNSksCiAgICAgICAgIE1hbGVfMTYgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxNiksCiAgICAgICAgIE1hbGVfMTcgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxNyksCiAgICAgICAgIE1hbGVfMTggID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxOCksCiAgICAgICAgIE1hbGVfMTkgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoxOSksCiAgICAgICAgIE1hbGVfMjAgID0gYl9hX1RyZWF0bWVudE1hbGUgKiBleHAoLShiX2xhbWJkYV9UcmVhdG1lbnRNYWxlKSoyMCkpICU+JSAKICBzZWxlY3QoLWMoY29udGFpbnMoImJfIikpKQoKRGlmZmVyZW5jZV9nZW5zX3Byb2R1Y3Rpdml0eSA8LSAKICBwcmVkcyAlPiUgCiAgZ3JvdXBfYnkoR2VuZXJhdGlvbiwgVHJlYXRtZW50LCBCbG9jaykgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgcGl2b3Rfd2lkZXIodmFsdWVzX2Zyb20gPSAiQ29sbGVjdGlvbl93aW5kb3dfb2Zmc3ByaW5nIiwgbmFtZXNfZnJvbSA9ICJUcmVhdG1lbnQiKSAlPiUgCiAgbXV0YXRlKGRpZmYubWMgPSBgTWFsZS1saW1pdGVkYCAtIENvbnRyb2wsCiAgICAgICAgIGRpZmYubWYgPSBgTWFsZS1saW1pdGVkYCAtIGBGZW1hbGUtbGltaXRlZGAsCiAgICAgICAgIGRpZmYuZmMgPSBgRmVtYWxlLWxpbWl0ZWRgIC0gQ29udHJvbCkgJT4lIAogIHNlbGVjdChHZW5lcmF0aW9uLCBCbG9jaywgY29udGFpbnMoImRpZmYiKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gY29udGFpbnMoImRpZmYiKSwgdmFsdWVzX3RvID0gInN1cnZpdmFsX2RpZmYiLCBuYW1lc190byA9ICJEaWZmZXJlbmNlIGNvbnRyYXN0IikgCgojIE1ha2UgdGhlIHRocmVlIHBsb3RzCgpMZWFmX3Bsb3RfbWNfcHJvZHVjdGl2aXR5X0IxIDwtCiAgRGlmZmVyZW5jZV9nZW5zX3Byb2R1Y3Rpdml0eSAlPiUKICBmaWx0ZXIoYERpZmZlcmVuY2UgY29udHJhc3RgID09ICJkaWZmLm1jIiAmIEJsb2NrID09ICIxIikgJT4lIAogIGdncGxvdChhZXMoc3Vydml2YWxfZGlmZiwgYXMuZmFjdG9yKEdlbmVyYXRpb24pKSkgKwogIHN0YXRfaW50ZXJ2YWwoLndpZHRoID0gYygwLjA1LCAwLjY2LCAwLjk1KSwgCiAgICAgICAgICAgICAgICBoZWlnaHQgPSAxLCBzaG93LmxlZ2VuZCA9IEYpICsKICByY2FydG9jb2xvcjo6c2NhbGVfY29sb3JfY2FydG9fZChwYWxldHRlID0gIlB1cnAiKSArCiAgI2Nvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMC4xLCAwLjMpKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9cmV2KSArCiAgZ2VvbV92bGluZShsaW5ldHlwZSA9IDIsIHhpbnRlcmNlcHQgPSAwLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJNYWxlIC0gQ29udHJvbFxuUHJvZHVjdGl2aXR5IGRpZmYuIiwKICAgICAgIHkgPSAiR2VuZXJhdGlvbiBvZiBpbmJyZWVkaW5nIikgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkKCkxlYWZfcGxvdF9tY19wcm9kdWN0aXZpdHlfQjIgPC0KICBEaWZmZXJlbmNlX2dlbnNfcHJvZHVjdGl2aXR5ICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYubWMiICYgQmxvY2sgPT0gIjIiKSAlPiUgCiAgZ2dwbG90KGFlcyhzdXJ2aXZhbF9kaWZmLCBhcy5mYWN0b3IoR2VuZXJhdGlvbikpKSArCiAgc3RhdF9pbnRlcnZhbCgud2lkdGggPSBjKDAuMDUsIDAuNjYsIDAuOTUpLCAKICAgICAgICAgICAgICAgIGhlaWdodCA9IDEsIHNob3cubGVnZW5kID0gRikgKwogIHJjYXJ0b2NvbG9yOjpzY2FsZV9jb2xvcl9jYXJ0b19kKHBhbGV0dGUgPSAiUHVycCIpICsKICAjY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjEsIDAuMykpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIk1hbGUgLSBDb250cm9sXG5Qcm9kdWN0aXZpdHkgZGlmZi4iLAogICAgICAgeSA9ICJHZW5lcmF0aW9uIG9mIGluYnJlZWRpbmciKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKTGVhZl9wbG90X21mX3Byb2R1Y3Rpdml0eV9CMSA8LQogIERpZmZlcmVuY2VfZ2Vuc19wcm9kdWN0aXZpdHkgJT4lCiAgZmlsdGVyKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCA9PSAiZGlmZi5tZiIgJiBCbG9jayA9PSAiMSIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJUZWFsR3JuIikgKwogICNjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTAuMSwgMC4zKSkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzPXJldikgKwogIGdlb21fdmxpbmUobGluZXR5cGUgPSAyLCB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDEpICsKICBsYWJzKHggPSAiTWFsZSAtIEZlbWFsZVxuUHJvZHVjdGl2aXR5IGRpZmYuIiwKICAgICAgIHkgPSBOVUxMKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKTGVhZl9wbG90X21mX3Byb2R1Y3Rpdml0eV9CMiA8LQogIERpZmZlcmVuY2VfZ2Vuc19wcm9kdWN0aXZpdHkgJT4lCiAgZmlsdGVyKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCA9PSAiZGlmZi5tZiIgJiBCbG9jayA9PSAiMiIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJUZWFsR3JuIikgKwogICNjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoLTAuMSwgMC4zKSkgKwogIHNjYWxlX3lfZGlzY3JldGUobGltaXRzPXJldikgKwogIGdlb21fdmxpbmUobGluZXR5cGUgPSAyLCB4aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDEpICsKICBsYWJzKHggPSAiTWFsZSAtIEZlbWFsZVxuUHJvZHVjdGl2aXR5IGRpZmYuIiwKICAgICAgIHkgPSBOVUxMKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKQoKTGVhZl9wbG90X2ZjX3Byb2R1Y3Rpdml0eV9CMSA8LQogIERpZmZlcmVuY2VfZ2Vuc19wcm9kdWN0aXZpdHkgJT4lCiAgZmlsdGVyKGBEaWZmZXJlbmNlIGNvbnRyYXN0YCA9PSAiZGlmZi5mYyIgJiBCbG9jayA9PSAiMSIpICU+JSAKICBnZ3Bsb3QoYWVzKHN1cnZpdmFsX2RpZmYsIGFzLmZhY3RvcihHZW5lcmF0aW9uKSkpICsKICBzdGF0X2ludGVydmFsKC53aWR0aCA9IGMoMC4wNSwgMC42NiwgMC45NSksIAogICAgICAgICAgICAgICAgaGVpZ2h0ID0gMSwgc2hvdy5sZWdlbmQgPSBGKSArCiAgcmNhcnRvY29sb3I6OnNjYWxlX2NvbG9yX2NhcnRvX2QocGFsZXR0ZSA9ICJQZWFjaCIpICsKICAjY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKC0wLjEsIDAuMykpICsKICBzY2FsZV95X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICBnZW9tX3ZsaW5lKGxpbmV0eXBlID0gMiwgeGludGVyY2VwdCA9IDAsIHNpemUgPSAxKSArCiAgbGFicyh4ID0gIkZlbWFsZSAtIENvbnRyb2xcblByb2R1Y3Rpdml0eSBkaWZmLiIsCiAgICAgICB5ID0gTlVMTCkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkKCkxlYWZfcGxvdF9mY19wcm9kdWN0aXZpdHlfQjIgPC0KICBEaWZmZXJlbmNlX2dlbnNfcHJvZHVjdGl2aXR5ICU+JQogIGZpbHRlcihgRGlmZmVyZW5jZSBjb250cmFzdGAgPT0gImRpZmYuZmMiICYgQmxvY2sgPT0gIjIiKSAlPiUgCiAgZ2dwbG90KGFlcyhzdXJ2aXZhbF9kaWZmLCBhcy5mYWN0b3IoR2VuZXJhdGlvbikpKSArCiAgc3RhdF9pbnRlcnZhbCgud2lkdGggPSBjKDAuMDUsIDAuNjYsIDAuOTUpLCAKICAgICAgICAgICAgICAgIGhlaWdodCA9IDEsIHNob3cubGVnZW5kID0gRikgKwogIHJjYXJ0b2NvbG9yOjpzY2FsZV9jb2xvcl9jYXJ0b19kKHBhbGV0dGUgPSAiUGVhY2giKSArCiAgI2Nvb3JkX2NhcnRlc2lhbih4bGltID0gYygtMC4xLCAwLjMpKSArCiAgc2NhbGVfeV9kaXNjcmV0ZShsaW1pdHM9cmV2KSArCiAgZ2VvbV92bGluZShsaW5ldHlwZSA9IDIsIHhpbnRlcmNlcHQgPSAwLCBzaXplID0gMSkgKwogIGxhYnMoeCA9ICJGZW1hbGUgLSBDb250cm9sXG5Qcm9kdWN0aXZpdHkgZGlmZi4iLAogICAgICAgeSA9IE5VTEwpICsKICB0aGVtZV9idygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpCgpgYGAKCiMjIEZpZ3VyZSAyIGFuZCBGaWd1cmUgU1gKCmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTB9CihubF9wMSAvIChJbml0aWFsX3Byb2R1Y3Rpdml0eV9wbG90X0IxICsgZGVjYXlfcGxvdF9CMSkpIC8gKExlYWZfcGxvdF9tY19wcm9kdWN0aXZpdHlfQjEgKyBMZWFmX3Bsb3RfbWZfcHJvZHVjdGl2aXR5X0IxICsgTGVhZl9wbG90X2ZjX3Byb2R1Y3Rpdml0eV9CMSkgKwogIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gJ2EnKQpgYGAKCioqRmlndXJlIDIqKi4gdGhlIGZpZ3VyZSB0byBlbmQgYWxsIGZpZ3VyZXMgYWdhaW4uIEJsb2NrIDEKCiR+JAoKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMH0KKG5sX3AyIC8gKEluaXRpYWxfcHJvZHVjdGl2aXR5X3Bsb3RfQjIgKyBkZWNheV9wbG90X0IyKSkgLyAoTGVhZl9wbG90X21jX3Byb2R1Y3Rpdml0eV9CMiArIExlYWZfcGxvdF9tZl9wcm9kdWN0aXZpdHlfQjIgKyBMZWFmX3Bsb3RfZmNfcHJvZHVjdGl2aXR5X0IyKSArCiAgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAnYScpCmBgYAoKKipGaWd1cmUgU1gqKi4gdGhlIGZpZ3VyZSB0byBlbmQgYWxsIGZpZ3VyZXMgYWdhaW4uIEJsb2NrIDIKCgo=